canvas实现简易电子签名

350 阅读1分钟

使用Canvas实现简易的电子签名

我们项目的技术栈是 React+Mobx,想要做电子签名,这个也是百度到的方法,在此作为记录,为后续开发做准备

一、先看下效果:

交互如下:

image.png

最终得到的是图片

image.png

二、具体代码实现:

html文件如下:

import store from './index-store.jsx';
import './index.less';

const XXX = observer(() => {
    useEffect(() => {
        store.init()
    }, []);

    return useObserver(() => (
        <div>
            <canvas id="signatureCanvas" width="400" height="200"></canvas>
            <br />
            <Button id="clearButton" onClick={store.clearCanvas}>清除签名</Button>
            <Button id="saveButton" onClick={store.saveCanvas}>保存签名</Button>
        </div>
    ));
});

export default XXX;

css文件如下:

canvas {
    border: 1px solid black;
    background-color: #fff;
}
button {
    margin: 10px;
}

js文件如下:

@observable
isDrawing = false;

@observable
lastX = 0;

@observable
lastY = 0;

@observable
canvas = null;

@observable
ctx = null;

@action
init = () => {
    this.canvas = document.getElementById("signatureCanvas");
    console.log(22222)
    this.ctx = this.canvas.getContext("2d");
    this.canvas.addEventListener("mousedown", this.startDrawing);
    this.canvas.addEventListener("mousemove", this.draw);
    this.canvas.addEventListener("mouseup", this.stopDrawing);
    this.canvas.addEventListener("mouseout", this.stopDrawing);

    const clearButton = document.getElementById("clearButton");
    clearButton.addEventListener("click", this.clearCanvas);

    const saveButton = document.getElementById("saveButton");
    saveButton.addEventListener("click", this.saveCanvas);
}

clearCanvas() {
    const canvas = document.getElementById("signatureCanvas");
    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

saveCanvas() {
    const canvas = document.getElementById("signatureCanvas");
    var imageData = canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height);
    for (var i = 0; i < imageData.data.length; i += 4) {
    // 当该像素是透明的,则设置成白色
    if (imageData.data[i + 3] == 0) {
        imageData.data[i] = 255;
        imageData.data[i + 1] = 255;
        imageData.data[i + 2] = 255;
        imageData.data[i + 3] = 255;
    }
    }
    canvas.getContext("2d").putImageData(imageData, 0, 0);
    const image = canvas.toDataURL("image/png");
    const link = document.createElement("a");
    link.download = "signature.png";
    link.href = image;
    link.click();
}

startDrawing(e) {
    this.isDrawing = true;
    [this.lastX, this.lastY] = [e.offsetX, e.offsetY];
}

draw(e) {
    if (!this.isDrawing) return;
    this.canvas = document.getElementById("signatureCanvas");
    this.ctx = this.canvas.getContext("2d");
    this.ctx.beginPath();
    this.ctx.moveTo(this.lastX, this.lastY);
    this.ctx.lineTo(e.offsetX, e.offsetY);
    this.ctx.stroke();
    [this.lastX, this.lastY] = [e.offsetX, e.offsetY];
}

stopDrawing() {
    this.isDrawing = false;
}
吃水不忘挖井人,参考链接:www.jb51.net/article/279…