console
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="sign-page">
<div class="canvas-box">
<div class="canvas" ontouchstart="methods.canvasTouchEvent(event,'canvasStart')"
ontouchmove="methods.canvasTouchEvent(event,'canvasMove')"
ontouchend="methods.canvasTouchEvent(event,'canvasEnd')">
<div class="title">请在该区域内工整书写您的签名</div>
</div>
</div>
<p class="clearCanvas" onclick="methods.saveOrClear('clear')">清 除</p>
<p class="saveCanvas" onclick="methods.saveOrClear('save')">保 存</p>
</div>
</div>
<script>
const temp = {
canvas: null, // 画布el对象
cxt: null, // 上下文
stageInfo: null, // 返回canvas的大小及位置
isSign: false //未签名提示
}
const data = new Proxy(temp, {
set(target, property, value, receiver) {
if (property === 'isSign') {
console.log(value);
document.querySelector('.title').style.display = value ? 'none' : 'block'
}
return Reflect.set(target, property, value);
},
get(target, key) {
return Reflect.get(target, key);
},
})
const methods = {
/*
* 画布初始化事件
*/
initCanvas(obj) {
data.canvas = document.createElement('canvas'); // 指定canvas
obj.el.appendChild(data.canvas);
data.cxt = data.canvas.getContext('2d'); // 设置2D渲染区域
data.canvas.width = obj.el.clientWidth;
data.canvas.height = obj.el.clientHeight;
data.cxt.fillStyle = '#ffffff';
data.cxt.strokeStyle = '#000000';
data.cxt.fillRect(0, 0, data.canvas.width, data.canvas.width);
data.cxt.lineWidth = 2; // 设置线的宽度
data.cxt.lineCap = 'round';
data.stageInfo = data.canvas.getBoundingClientRect();
},
/*
* 画布touch相关事件处理
*/
canvasTouchEvent(e, type) {
const cxt = data.cxt;
const postion = [e.changedTouches[0].pageX - data.stageInfo.left, e.changedTouches[0].pageY - data.stageInfo.top]
const handle = {
canvasStart: () => {
cxt.beginPath();
cxt.moveTo(...postion);
},
canvasMove: () => {
if (!e && !e.preventDefault) return;
e.preventDefault();
cxt.lineTo(...postion);
cxt.stroke();
data.isSign = true;
},
canvasEnd: () => cxt.closePath
}
handle[type]();
},
/*
* 清除和保存事件
*/
saveOrClear(type) {
if (type === 'clear') {
data.cxt.clearRect(0, 0, data.canvas.width, data.canvas.height);
data.isSign = false;
return false;
}
if (data.isSign) {
const imgBase64 = data.canvas.toDataURL();
console.log(imgBase64);
} else {
data.$dialog.alert({ title: '错误', message: '请绘制签名', messageAlign: 'center' });
}
}
}
const p = new Proxy(data, {
set(target, property, value, receiver) {
console.log(key);
if (property === 'isSign') {
console.log('isSign');
}
return Reflect.set(target, key, value);
}
})
setTimeout(() => {
methods.initCanvas({ el: document.querySelector('.canvas') });
})
</script>
<style>
.canvas-box {
min-heght:400px;
width: calc(100% - 68px);
height: calc(100% - 180px);
margin-bottom: 38px;
position: relative;
border-radius: 6px;
background: #fff;
padding: 34px;
}
.canvas {
background: #fff;
height: 100%;
width: 100%;
border: 1px dashed #848588;
position: relative;
border-radius: 6px;
}
.saveCanvas,
.clearCanvas {
padding: 10px 0;
background: rgba(207, 225, 245, 1);
width: 45%;
text-align: center;
float: left;
color: #3F8EE8;
}
.saveCanvas {
margin-left: 10%;
}
.sign-page {
background: #EDF1F6;
width: calc(100% - 60px);
height: calc(100% - 96px);
padding: 58px 30px 38px;
position: fixed;
top: 0;
left: 0;
}
.title {
text-orientation: mixed;
font-size: 18px;
color: #A0ACBF;
position: absolute;
padding: 10%;
top: 0;
left: 0;
}
</style>
</body>
</html>