前言:一般在一些后台的流程资料以及审核的场景中会需要电子签名,介绍一种用canvas实现的电子签名,此案例用的是原生js
效果展示:
一、html和css:
<div class="divCla2">
<canvas id="myCanvas" width="600" height="400"></canvas>
<button class="clearBtn">撤销</button>
<button class="downBtn">下载</button>
</div>
.divCla2{
border: 1px solid #817e7e;
width: 600px;
height: 400px;
}
二、js实现逐步分析:(如果着急实现功能可以直接下滑到三)
整个电子签名的流程无非就是按下鼠标、画线、松开鼠标、停止画线
1、需要定义三个值:是否按下、当前的x坐标和y坐标,鼠标按下的时候就开始画
//获取canvas
let canvas = document.getElementById("myCanvas");
// 状态status,用于标记开始和暂停
let status = false;
//xy坐标
let x = 0;
let y = 0;
// 鼠标按下的时候开始画
canvas.addEventListener("mousedown", (e) => {
status = true;
x = e.offsetX;
y = e.offsetY;
console.log(x, y, status);
});
2、鼠标松开时就改变status的值为false
canvas.addEventListener("mouseup", () => {
status = false;
});
3、鼠标移出画布时也一样:
canvas.addEventListener("mouseout", (e) => {
status = false;
});
/4、鼠标移入并且status状态为true的时候就是可以画的
canvas.addEventListener("mousemove", () => {
if (!status) return;
});
5、创建一个二维平面当做“笔”,并且加一些样式,比如描边颜色、拐角形状、线条末端形状、线条宽度等,然后绘制线条,可以看每一步的注释:
let ctx = canvas.getContext("2d"); // 建立二维平面
canvas.addEventListener("mousemove", (e) => {
if (!status) return;
//设置描边颜色
ctx.strokeStyle = "#000";
//拐角形状
ctx.lineJoin = "round";
//线条宽度
ctx.lineWidth = 2;
//末端形状
ctx.lineCap = "round";
//创建一条路径
ctx.beginPath();
//线条从哪里开始
ctx.moveTo(x, y);
//线条从哪里结束
ctx.lineTo(e.offsetX, e.offsetY);
//绘制路径
ctx.stroke();
//作为下次开始使用
x = e.offsetX;
y = e.offsetY;
});
这样就已经可以绘制了
6、如果写错了,需要撤销功能,使用clearRect方法:
//撤销
const clearBtn = document.querySelector(".clearBtn");
clearBtn.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
7、 还要配合应用场景,有些时候需要将电子签名转化成图片,然后进行下载或者传给后端等,实现下载:
//下载
let downBtn=document.querySelector(".downBtn");
downBtn.addEventListener("click",()=>{
let a = document.createElement("a");
a.href = canvas.toDataURL("image/png");
a.download = "canvas.png";
a.click();
})
三、完整代码,可以直接复制使用:
let canvas = document.getElementById("myCanvas");
let status = false;
let x = 0;
let y = 0;
canvas.addEventListener("mousedown", (e) => {
status = true;
x = e.offsetX;
y = e.offsetY;
console.log(x, y, status);
});
canvas.addEventListener("mouseup", () => {
status = false;
});
canvas.addEventListener("mouseout", (e) => {
status = false;
});
canvas.addEventListener("mousemove", () => {
if (!status) return;
});
let ctx = canvas.getContext("2d"); // 建立二维平面
canvas.addEventListener("mousemove", (e) => {
if (!status) return;
ctx.strokeStyle = "#000";
ctx.lineJoin = "round";
ctx.lineWidth = 2;
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
x = e.offsetX;
y = e.offsetY;
});
//撤销
const clearBtn = document.querySelector(".clearBtn");
clearBtn.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
//下载
let downBtn=document.querySelector(".downBtn");
downBtn.addEventListener("click",()=>{
let a = document.createElement("a");
a.href = canvas.toDataURL("image/png");
a.download = "canvas.png";
a.click();
})