1. 程式人生 > 其它 >20220317 - 一個拖動畫矩形並撤銷或刪除步驟的例子

20220317 - 一個拖動畫矩形並撤銷或刪除步驟的例子

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>click & drag example</title>
    <style>
    #canvas{
        width: 1920px; 
        height: 647px; 
        border
: 1px solid #999; background-image: url("http://www-file.huawei.com/-/media/corp2020/home/banner/5/vmall-backtoschool-2.jpg"); } </style> </head> <body> <canvas id="canvas" width="1920px" height="647px"></canvas> <select name="mode" id="mode"> <
option value="rect">繪製矩形框</option> <option value="point">標記關鍵點</option> </select> <button id="undo" onclick="undo()">撤銷</button> <button id="del" onclick="del(1)">刪除2</button> <button id="del" onclick="del(2)">刪除3</button
> <button id="del" onclick="del(3)">刪除4</button> <script> const canvas = document.getElementById('canvas'), context = canvas.getContext('2d'), pointArray = [], rectArray = [], history = [] let dragging = false, mode = 'rect', mousedown = null function Point(x, y, type) { this.x = x this.y = y this.type = type } function windowToCanvas(x, y, type) { var bbox = canvas.getBoundingClientRect(); return new Point(x - bbox.left * (canvas.width / bbox.width), y - bbox.top * (canvas.height / bbox.height), type) } function drawPoint(point) { context.save() context.fillStyle = point['type'] === 3 ? 'red' : 'green' context.beginPath(); context.arc(point.x, point.y, 3, 0, Math.PI * 2, true) context.fill() context.font = "20px serif"; context.fillText((pointArray.length).toString(), point.x - 5, point.y - 10) context.restore() pointArray.push(point) } function updateRect(point, mousedown) { let w = Math.abs(point.x - mousedown.x) let h = Math.abs(point.y - mousedown.y) let left = point.x > mousedown.x ? mousedown.x : point.x let top = point.y > mousedown.y ? mousedown.y : point.y context.save(); context.beginPath(); context.rect(left, top, w, h); context.stroke(); context.restore(); } function showLastHistory() { context.putImageData(history[history.length - 1]['data'], 0, 0) } function undo() { if (history.length > 1) { history[history.length - 1]['mode'] === 'point' && pointArray.pop() history.pop() showLastHistory() } } function del(i) { if (history.length > 1) { history[history.length - 1]['mode'] === 'point' && pointArray.splice(i + 1, 1) history[i + 1] = null let i2 = i + 1 - 1 while (i2 > 0) { if (history[i2]) { context.putImageData(history[i2]['data'], 0, 0) break } i2-- } let index = i + 1 + 1; for (; index < history.length; index++) { if (!history[index]) { continue } let p0 = history[index]['rect_point'][0] let p1 = history[index]['rect_point'][1] updateRect(p0, p1) } } } function addHistoy(arr) { history.push({ mode, data: context.getImageData(0, 0, canvas.width, canvas.height), rect_point: arr }) } document.getElementById('mode').onchange = function(e) { mode = e.target.value } canvas.onmousedown = function(e) { e.preventDefault(); mousedown = windowToCanvas(e.clientX, e.clientY, e.which) dragging = true } canvas.onmousemove = function(e) { e.preventDefault(); if (dragging && mode === 'rect') { showLastHistory() updateRect(windowToCanvas(e.clientX, e.clientY, e.which), mousedown) } } addHistoy() canvas.onmouseup = function(e) { e.preventDefault(); dragging = false mode === 'point' && drawPoint(mousedown) addHistoy([windowToCanvas(e.x, e.y, e.which), mousedown]) } // 阻止頁面的右擊選單欄 canvas.oncontextmenu = function(e) { e.preventDefault() } </script> </body> </html>