需求
需求是做不完了,福利也被砍了,旅游也泡汤了,手上有2个需求,还没做完,PM就来新需求了。
开发一个签名板:要求PC端/移动端都能用、扫码签名、实时同步、可以改变笔画粗细、笔画颜色、可以生成base64图片。
方案分析canvas
1.获取页面[canvas
]元素,设置宽高(800*200)
2.通过**HTMLCanvasElement.getContext()
** 方法返回[canvas
] 的上下文ctx
3.初始化ctx基础属性
- 线条颜色
- 线条宽度
- 线条末端形状
4.开始绘画
- 监听鼠标事件
- 绘制起点、终点
5.生成一个移动端链接二维码
6.在移动端签名时,通过WebSocket,实时传递数据给PC端。
涉及知识点
Canvas涉及特性:
- 基本属性
getContext()
strokeStyle
fillStyle
lineCap
lineJoin
- 路径绘制
beginPath()
lineTo()
moveTo()
- 其他方法(生成base64,清除画板)
toDataURL()
clearRect()
涉及鼠标事件:
mousemove
mousedown
mouseup
mouseout
涉及移动端触摸事件:
touchstart
touchend
touchmove
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>canvas-sign</title>
<style>
html,
body {
margin: 0;
}
.container {
width: calc(100vw - 40px);
height: calc(100vh - 40px);
padding: 20px;
}
.canvas-body {
width: calc(80vw);
height: calc(80vh);
margin: 20px auto;
}
#sign {
background-color: #f3f5f7;
border-radius: 4px;
border: 1px dashed #0F6BFF;
}
#img {
margin: 20px;
border-radius: 4px;
background-color: #f3f5f7;
display: none;
}
#img.show {
display: inline-block;
}
.btns {
width: calc(80vw - 40px);
text-align: right;
margin: 0 auto;
}
@media screen and (orientation: portrait) {
.qrcode {
display: none;
}
}
</style>
<script type="text/javascript" src="https://static.runoob.com/assets/qrcode/qrcode.min.js"></script>
</head>
<body>
<div class="container">
<div id="canvas-body" class="canvas-body">
<canvas id="sign" style="width: 100%; height: 100%;"></canvas>
<div class="qrcode">
扫码签名
<div id="qrcode"></div>
</div>
</div>
<div class="btns">
<button id="reset">重置</button>
<button id="showImg">生成图片</button>
</div>
</div>
<div id="img">
</div>
<script>
let canvasBody = document.getElementById('canvas-body');
let canvas = document.getElementById('sign');
let reset = document.getElementById('reset');
let showImg = document.getElementById('showImg');
let img = document.getElementById('img');
canvas.width = canvasBody.clientWidth;
canvas.height = canvasBody.clientHeight;
let ctx = canvas.getContext('2d');
ctx.lineWidth = 10;
ctx.strokeStyle = '#333';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
let isDrawing = false;
let dataURL = '';
let initX;
let initY;
// 事件监听
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
initX = e.offsetX;
initY = e.offsetY
});
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
// 绘制
function draw(e) {
if (!isDrawing) return
ctx.beginPath();
// 起点
ctx.moveTo(initX, initY);
// 终点
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
initX = e.offsetX;
initY = e.offsetY
}
function clear() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (dataURL) {
dataURL = '';
img.innerHTML = '';
img.classList.remove('show');
}
}
function canvasToBase64() {
dataURL = canvas.toDataURL();
// let oGrayImg = new Image();
// oGrayImg.src = dataURL;
// img.classList.add('show');
// img.appendChild(oGrayImg)
alert(`${dataURL}`)
}
reset.addEventListener('click', clear);
showImg.addEventListener('click', canvasToBase64);
</script>
<script>
let qrcode = new QRCode(document.getElementById('qrcode'), {
width: 96,
height: 96
})
qrcode.makeCode('https://canvas-sign.vercel.app/');
</script>
</body>
</html>
以上代码,未开发的点
- 移动端触摸事件,禁止移动端屏幕,修改笔画粗细、笔画颜色
- 实时同步WebSocket
- 实时同步笔画时,如何让笔画有实时同步一笔一画的效果?下图
以上就是JS前端使用canvas编写一个签名板的详细内容,更多关于JS canvas签名板的资料请关注编程网其它相关文章!