用JS制作canvas画板

之前写了一篇随笔是讲 fabric.js 的,基于vue的,查看:https://www.cnblogs.com/reround/p/11468844.html

如果不基于vue用js也是可以实现的

代码如下,直接copy到html文件里就可以,无需加载其他插件,代码里都有注释

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>js画板</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            html,
            body,
            .container {
                height: 100%;
            }
            
            #controls {
                padding-left: 20px;
                height: 60px;
                line-height: 60px;
            }
            
            canvas {
                border: 1px solid #ccc;
                margin-left: 20px;
            }
            #controls li {
                list-style: none;
                display: inline-block;
                margin-right: 10px;
            }
            #img{
                width: 1000px;
                height: 400px;
                background: #eee;
                display: inline-block;
                margin-left: 20px;
            }
            .word{
                margin: 10px 0 10px 20px;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <ul id="controls">
                <li>
                    <label for="shape" class="label">选择形状 : </label>
                    <select id="shape">
                        <option value="rect">矩形</option>
                        <option value="line">直线</option>
                        <!--<option value="circle">内切圆</option>-->
                        <option value="circle">圆</option>
                        <!--<option value="circle2">中心圆</option>-->
                        <option value="poly">多边形</option>
                        <option value="pen">铅笔</option>
                        <option value="eraser">橡皮擦</option>
                    </select>
                </li>

                <li>
                    <label for="color" class="label">选择颜色 : </label>
                    <input type="color" id="color" value="#ff0000">
                </li>
                <li>
                    <label for="color" class="label">选择线宽 : </label>
                    <input type="number" id="width" value="1" step="1" min="2" max="20">
                </li>
                <li>
                    <label for="shape" class="label">选择方式 : </label>
                    <select id="style">
                        <option value="stroke">描边</option>
                        <option value="fill">填充</option>
                    </select>
                </li>
                <li>
                    <label for="side" class="label">选择边数 : </label>
                    <input type="number" id="side" value="3" min="3" max="20">
                </li>
                <li>
                    <button id="redo">撤销</button>
                    <button id="clear">清空</button>
                    <button id="save">保存</button>
                </li>
            </ul>
            <div class="word">canvas面板:</div>
            <canvas width="1000px" height="400px"></canvas>
            <div class="word">显示保存的图片:</div>
            <img src="" id="img" alt="" />
        </div>

        <script>
            var canvas = document.querySelector("canvas");
            var canvasObj = canvas.getContext("2d");
            var shape = document.querySelector("#shape");
            var color = document.querySelector("#color");
            var width = document.querySelector("#width");
            var style = document.querySelector("#style");
            var side = document.querySelector("#side");
            var redo = document.querySelector("#redo");
            var save = document.querySelector("#save");
            var clear = document.querySelector("#clear");
            var data = [];
            var s = "rect";
            shape.onchange = function() {   //获取形状
                s = this.value;
            };
            var c = "#f00";
            color.onchange = function() {   //获取颜色
                c = this.value;
            };
            var w = "2";
            width.onchange = function() {    //获取宽度
                w = this.value;
            };
            var st = "stroke";
            style.onchange = function() {   //获取绘画方式
                st = this.value;
            };
            var sd = "3";
            side.onchange = function() {   //获取边数
                sd = this.value;
            };
            canvas.onmousedown = function(e) {   //canvas上按下鼠标事件
                var ox = e.offsetX;
                var oy = e.offsetY;
                var draw = new Draw(canvasObj, {
                    color: c,
                    width: w,
                    style: st,
                    side: sd
                });
                if(s === "pen") {
                    canvasObj.beginPath();
                    canvasObj.moveTo(ox, oy);
                }
                canvas.onmousemove = function(e) {     //移动事件
                    var mx = e.offsetX;
                    var my = e.offsetY;
                    if(s !== "eraser") {
                        canvasObj.clearRect(0, 0, 1000, 400);
                        if(data.length !== 0) {
                            canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400); //将数据添加到画布中
                        }
                    }
                    draw[s](ox, oy, mx, my, sd);
                };
                document.onmouseup = function() {
                    data.push(canvasObj.getImageData(0, 0, 1000, 400)); //获取画布中的数据
                    canvas.onmousemove = null;   
                    document.onmouseup = null;
                }
            };
            redo.onclick = function() {   //撤回
                if(data.length == 0) {
                    alert("没有可以撤销的内容了");
                    return;
                }
                canvasObj.clearRect(0, 0, 1000, 400);
                data.pop();
                if(data.length == 0) {
                    return;
                }
                canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400);
            };
            save.onclick = function() {    //保存
                var r = canvas.toDataURL();
                document.getElementById('img').src = r
            };
            clear.onclick = function() {   //清除
                canvasObj.clearRect(0, 0, 1000, 400);
                data = [];
            }
            class Draw {
                constructor(canvasObj, option) {
                    this.canvasObj = canvasObj;
                    this.color = option.color;
                    this.width = option.width;
                    this.style = option.style;
                }
                init() { //初始化
                    this.canvasObj.strokeStyle = this.color;
                    this.canvasObj.fillStyle = this.color;
                    this.canvasObj.lineWidth = this.width;
                }
                rect(ox, oy, mx, my) {
                    this.init();
                    this.canvasObj.beginPath();
                    this.canvasObj.rect(ox, oy, mx - ox, my - oy);
                    this.canvasObj[this.style]();

                }
                line(ox, oy, mx, my) {
                    this.init();
                    this.canvasObj.beginPath();
                    this.canvasObj.moveTo(ox, oy);
                    this.canvasObj.lineTo(mx, my);
                    this.canvasObj.stroke();
                }
                circle(ox, oy, mx, my) { //
                    this.init();
                    this.canvasObj.beginPath();
                    var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
                    this.canvasObj.arc(ox, oy, r, 0, 2 * Math.PI);
                    this.canvasObj[this.style]();
                }
                poly(ox, oy, mx, my, sd) {
                    this.init();
                    this.canvasObj.save();
                    canvasObj.translate(ox, oy);
                    this.canvasObj.rotate(Math.PI / 2);
                    var angle = Math.PI / sd;
                    var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
                    var x = Math.cos(angle) * r;
                    var y = Math.sin(angle) * r;
                    this.canvasObj.beginPath();
                    this.canvasObj.moveTo(x, y);
                    for(var i = 0; i < sd; i++) {
                        this.canvasObj.lineTo(x, -y);
                        this.canvasObj.rotate(-angle * 2)
                    }
                    this.canvasObj[this.style]();
                    this.canvasObj.restore()
                }
                pen(ox, oy, mx, my) {
                    this.init();
                    this.canvasObj.lineTo(mx, my);
                    this.canvasObj.stroke();
                }
                eraser(ox, oy, mx, my) {
                    console.log(canvas.style)
                    console.log(canvas.style.cursor)
                    this.canvasObj.clearRect(mx, my, 20, 20);
                }
            }
        </script>
    </body>
</html>

猜你喜欢

转载自www.cnblogs.com/reround/p/12171479.html