使用canvas实现手写板(移动端)

<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1">
<title>使用canvas实现手写板(移动端)</title>
</head>
<body>
<style type="text/css">
*{margin:0;padding:0;}
.canvas-container{position:relative;margin:4vw auto 0;width:92vw;height:56.856vw;background:#cce8cf;}
.canvas-container [data-action=clear],.canvas-container [data-action=save]{position:absolute;bottom:2vw;margin:0 2vw 0 0;padding:.4vw 2vw;border:.1vw solid #adadad;cursor:pointer;user-select:none;}
.canvas-container [data-action=clear]{right:9.7vw;}
.canvas-container [data-action=save]{right:0;}
</style>
<div class="canvas-container" id="canvas-demo">
    <button data-action="clear" id="button-clear-canvas-demo">清除</button>
    <button data-action="save" id="button-save-canvas-demo">保存</button>
</div>
<script type="text/javascript" src="./jquery.min.js"></script>
<script type="text/javascript">
/**
 * 初始化画布
 *
 * @param object options 画布参数,画布容器ID为必填参数,其余参数(如画笔宽度、画笔颜色等为选填参数)
 * @return void
 */
function initCanvas(options) {
    this.lineWidth = 5; // 画笔宽度(决定线条粗细)
    this.color = '#4e6ef2'; // 画笔颜色
    this.background = '#cce8cf'; // 手写区域背景色

    for (var i in options) {
        this[i] = options[i];
    }

    this.container = document.getElementById(this.key); // 画布容器
    this.buttonClear = document.getElementById('button-clear-' + this.key); // 清除画布内容按钮
    this.buttonSave = document.getElementById('button-save-' + this.key); // 保存画布按钮

    this.canvas = document.createElement('canvas');
    this.container.appendChild(this.canvas);
    this.cxt = this.canvas.getContext('2d');
    this.canvas.width = this.container.clientWidth;
    this.canvas.height = this.container.clientHeight;
    this.cxt.fillStyle = this.background;
    this.cxt.fillRect(0, 0, this.canvas.width, this.canvas.width);
    this.cxt.strokeStyle = this.color;
    this.cxt.lineWidth = this.lineWidth;
    this.cxt.lineCap = 'round';

    // 获取坐标函数
    this.getCoordinate = function (e) {
        // 获取光标的坐标(注:canvas坐标系是以canvas左上角为原点的,而光标的坐标系是以页面左上角为原点的,故需要转换)
        var x = e.changedTouches[0].pageX - $(this.canvas).offset().left;
        var y = e.changedTouches[0].pageY - $(this.canvas).offset().top;
        return {
            x: x,
            y: y
        };
    }.bind(this);

    // 开始绘制
    this.canvas.addEventListener('touchstart', function (e) {
        this.cxt.beginPath();
        var coordinate = this.getCoordinate(e);
        this.cxt.moveTo(coordinate.x, coordinate.y);
    }.bind(this), false);

    // 正在绘制
    this.canvas.addEventListener('touchmove', function (e) {
        var coordinate = this.getCoordinate(e);
        this.cxt.lineTo(coordinate.x, coordinate.y);

        this.cxt.stroke();
    }.bind(this), false);

    // 结束绘制
    this.canvas.addEventListener('touchend', function () {
        this.cxt.closePath();
    }.bind(this), false);

    // 清除画布
    this.buttonClear.addEventListener('click', function () {
        this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }.bind(this), false);

    // 保存图片(将图片base64编码POST到服务器并保存成图片即可,这里不展示后端代码)
    this.buttonSave.addEventListener('click', function () {
        var imgBase64 = this.canvas.toDataURL(); // 图片base64编码
        console.log(imgBase64); // 将图片base64编码复制到地址栏可查看图片
    }.bind(this), false);
}

// 初始化画布
new initCanvas({
    key: 'canvas-demo' // 画布容器ID
});
</script>
</body>
</html>

Copyright © 2024 码农人生. All Rights Reserved