canvas畫圖小試

這幾天再研究canvas畫圖,簡單的寫了一個頁面,就是用來框物品的,暫時只是讓畫四邊形。
  • 直接上代碼就行了,註釋都寫的比較全了已經。javascript

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .father {
                position: relative;
                -moz-user-select: none;
                margin-left: 8%;
                margin-top: 3%;
            }
    
            .canvas {
                position: absolute;
                z-index: 1;
            }
    
            .canvas_bgp {
                position: absolute;
            }
        </style>
    </head>
    <body>
    <div class="father" onselectstart="return false;">
        <canvas id="canvas" class="canvas" width="800" height="500">當前瀏覽器不支持canvas,請更換瀏覽器使用!</canvas>
        <img src="./timg.jpg" class="canvas_bgp" width="800" height="500">
    </div>
    </body>
    </html>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript">
        let canvas = document.getElementById("canvas"); //獲取到canvas元素
        let context = canvas.getContext("2d"); //獲取上下文的環境
        let arrOld = []; //記錄歷史位置,回退的時候用
        let timeId; //去掉第二次點擊的影響
        let arr = []; //正在畫的圖形的位置信息
    
        // 畫點
        function drawPoint(cxt, x, y, w, borderWidth, borderColor, fillColor) {
            cxt.beginPath();
            cxt.moveTo(x - w, y - w);
            cxt.lineTo(x + w, y - w);
            cxt.lineTo(x + w, y + w);
            cxt.lineTo(x - w, y + w);
            cxt.lineWidth = borderWidth;
            cxt.strokeStyle = borderColor;
            cxt.fillStyle = fillColor;
            cxt.closePath();
            cxt.fill();
            cxt.stroke();
        }
    
        // 畫多邊形
        function drawPolygon(cxt, dbl, borderWidth, borderColor, fillColor, t) {
            for (let i = 0; i < dbl.length; i++) {
                drawPoint(cxt, dbl[i].x, dbl[i].y, 2, 1, 'black', 'skyblue');
            }
            cxt.moveTo(dbl[0].x, dbl[0].y);
            for (let i = 1; i < dbl.length; i++) {
                cxt.lineTo(dbl[i].x, dbl[i].y);
            }
            if (t) {
                cxt.closePath();
                cxt.fillStyle = fillColor;
                cxt.fill();
            }
            cxt.lineWidth = borderWidth;
            cxt.strokeStyle = borderColor;
            cxt.stroke();
        }
    
        // canvas.ondblclick = function () {
        function generate() {
            // clearTimeout(timeId);//清除第二次的點擊事件
            // 須要畫三個點以上才能閉合
            if (arr.length > 2) {
                // 再次添加起點,這樣回退的時候就不會出現一下消失兩個線條的狀況
                arr.push({x: arr[0].x, y: arr[0].y});
                drawPolygon(context, arr, 3, 'green', "rgba(0, 0, 0, 0)", false);
                // 將arr存起來
                arrOld.push(arr);
                // 在列表中添加一條信息
                addition(arr);
                // 這裏執行完成閉合以後,清空座標數組,便於另外新建
                arr = [];
                // 此處須要獲取全部點的座標
                console.log(arrOld);
            } else {
                alert("無可閉合的圖形")
            }
        }
    
        //單擊肯定點的位置
        canvas.onclick = function (e) {
            clearTimeout(timeId);//清除第二次的點擊事件
            timeId = setTimeout(function () {
                let x = e.offsetX;
                let y = e.offsetY;
                arr.push({x: x, y: y});
                drawPolygon(context, arr, 3, 'green');
                // 如今點擊四個點就閉合圖形,由於只要求是四邊形
                if(arr.length == 4){
                    generate();
                }
            }, 250)
        };
    
        //回退操做
        canvas.ondblclick = function () {
            clearTimeout(timeId);//清除第二次的點擊事件
        // function regression() {
            if(arr.length == 0 && arrOld.length == 0){
                alert("沒法回退");
                return;
            }
            if (arr.length > 0) {
                // 刪除在畫的
                arr = arr.slice(0, arr.length - 1);
            } else {
                // 刪除已經畫好的
                if (arrOld.length > 0) {
                    // 拿出歷史數組中最後一個
                    arr = arrOld[arrOld.length - 1].slice(0, arr.length - 1);
                    // 刪除歷史中最後一個
                    arrOld = arrOld.slice(0, arrOld.length - 1);
                }
            }
            //清空畫板,重畫
            clean();
        };
    
        //顯示線條
        canvas.onmousemove = function() {
            //清空畫板,重畫
            clean();
            //劃線不畫點
            if(arr.length > 0 && arr.length < 4){
                let bbox = canvas.getBoundingClientRect();
                let x =  event.clientX - bbox.left * (canvas.width/bbox.width);
                let y = event.clientY - bbox.top * (canvas.height/bbox.height);
                context.moveTo(arr[arr.length-1].x, arr[arr.length-1].y);
                context.lineTo(x, y);
                context.lineWidth = 3;
                context.strokeStyle = 'green';
                context.stroke();
            }
        };
    
        // 清空畫板,重畫
        function clean() {
            //清空畫板,重畫
            context.clearRect(0, 0, 800, 500);
            for (let i = 0; i < arrOld.length; i++) {
                drawPolygon(context, arrOld[i], 3, 'green', "rgba(0, 0, 0, 0)", false);
            }
            if (arr.length > 0) {
                drawPolygon(context, arr, 3, 'green');
            }
        }
    </script>
  • 心得就是canvas就是反覆的清除後再從新畫,由於是由點畫線,因此我在最後圖形完成的時候討巧多存了一個起點,這樣在回退操做的時候就不會出現去掉一個點從而少了兩根線的問題。
相關文章
相關標籤/搜索