canvas 签字画板 移动端及pc端
2021-11-25 本文已影响0人
alice_沉默如初
利用canvas,在移动端和pc端生成签字画板,签字并保存base64图片传给后端
html代码块
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no,minimal-ui">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="email=no">
<title>Title</title>
<style>
html,body{
width: 100%;
margin: 0;
padding: 0;
}
body.popup-open {
position: fixed;
}
.sign-dialog{
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 8;
}
.sign-dialog .content{
position: absolute;
top: 50%;
left: 50%;
width: 80%;
height: 320px;
transform: translate(-50%,-50%);
background: #fff;
border-radius: 0.5rem;
padding: 1rem;
z-index: 2;
}
.sign-dialog .content h6{
font-size: 0.75rem;
margin:0;
margin-bottom: 0.5rem;
}
.sign-dialog #canvasbox{
border: 1px solid #333;
border-radius: 0.8rem;
}
.sign-dialog .btns{
/*display: flex;*/
/*justify-content: end;*/
margin-top: 0.5rem;
text-align: right;
}
.sign-dialog .btns p{
display: inline-block;
width: 4rem;
margin-left: 0.3rem;
font-size: 0.9rem;
line-height: 1.8rem;
text-align: center;
color: #fff;
text-indent: 0;
border-radius: 0.25rem;
background: #d75c0a;
}
</style>
</head>
<body>
<div class="sign-dialog">
<div class="content">
<h6>签字:</h6>
<canvas id="canvasbox" width="500" height="250"></canvas>
<div class="btns">
<p class="sign-clearbtn">清空</p>
<p class="sign-savebtn">确定</p>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script>
/*获取设备宽度,设置根字体大小*/
document.documentElement.style.fontSize = document.documentElement.clientWidth * 20 / 375 + "px";
window.onresize = function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth * 20 / 375 + "px";
}
$(function () {
initPage.init();
})
var initPage = {
init: function () {
this.sign();
},
sign: function () {
$('.img-wrap').click(function () {
closeBodyScroll();
$('.sign-dialog').show();
let width = 300;
let height = 200;
if($('.sign-dialog .content')){
width = $('.sign-dialog .content').width();
height = $('.sign-dialog .content').height() * 0.7;
}
$('#canvasbox').attr('width',width)
$('#canvasbox').attr('height',height)
sign();
})
$('.sign-savebtn').click(function () {
var canvasbox = document.getElementById("canvasbox");
console.log(canvasbox.toDataURL("image/png"))
clearCanvas();
$('.sign-dialog').hide();
openBodyScroll();
})
$('.sign-clearbtn').click(function () {
clearCanvas();
})
}
}
function sign() {
var canvasbox = document.getElementById("canvasbox");
var ctx = canvasbox.getContext("2d");
var iscanvas = false;
let vertex = document.getElementById('canvasbox').getBoundingClientRect();
if(checkBrowerType() === 'pc'){
var offsetX = '';
var offsetY = '';
canvasbox.addEventListener("mousedown", function (e) {
iscanvas = true;
offsetX = e.offsetX;
offsetY = e.offsetY;
})
canvasbox.addEventListener("mousemove", function (e) {
if (iscanvas) {
ctx.beginPath();
ctx.moveTo(offsetX, offsetY)
ctx.lineTo(e.offsetX, e.offsetY)
ctx.lineWidth = 2;
ctx.stroke()
offsetX = e.offsetX;
offsetY = e.offsetY;
}
})
canvasbox.addEventListener("mouseup", function () {
iscanvas = false;
})
canvasbox.addEventListener("mouseleave", function () {
iscanvas = false;
})
}else{
// 获取 canvas 相对于视口的位置。
let vertex = document.getElementById('canvasbox').getBoundingClientRect();
let t = vertex.top;
let l = vertex.left
canvasbox.addEventListener("touchstart", function (e) {
e.preventDefault();
iscanvas = true;
ctx.beginPath();
ctx.moveTo(e.changedTouches[0].clientX - l,e.changedTouches[0].clientY - t );
})
canvasbox.addEventListener("touchmove", function (e) {
if (iscanvas) {
ctx.lineTo(e.changedTouches[0].clientX - l,e.changedTouches[0].clientY - t );
ctx.lineWidth = 2;
ctx.lineJoin = 'round';
ctx.stroke()
}
})
canvasbox.addEventListener("touchend", function () {
iscanvas = false;
ctx.closePath();
})
canvasbox.addEventListener("touchcancel", function () {
iscanvas = false;
ctx.closePath();
})
}
}
//清空画板
function clearCanvas() {
var canvasbox = document.getElementById("canvasbox");
var ctx = canvasbox.getContext("2d");
ctx.closePath();
ctx.clearRect(0, 0, canvasbox.offsetWidth, canvasbox.offsetHeight);
}
//关闭body滚动轴
function closeBodyScroll() {
window.lockMaskScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
document.body.classList.add('popup-open');
document.body.style.top = -window.lockMaskScrollTop + "px";
}
//打开body滚动轴
function openBodyScroll() {
if (document.body.classList.contains('popup-open')) {
document.body.classList.remove('popup-open');
document.documentElement.scrollTop = window.lockMaskScrollTop;
}
}
//判断 设备信息 是移动端还是pc端
function checkBrowerType() {
var system = {
win: false,
mac: false,
xll: false,
ipad: false,
};
//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = p == "X11" || p.indexOf("Linux") == 0;
system.ipad = navigator.userAgent.match(/iPad/i) != null ? true : false;
if(system.win || system.mac || system.xll || system.ipad){
return 'pc';
}else{
return 'mobile';
}
}
</script>
</body>
</html>