Canvas:橡皮筋線條繪制
阿新 • • 發佈:2018-11-24
分享圖片 true 存在 什麽 can scrip 簡單的 恢復 des
Canvas:橡皮筋線條繪制
效果演示
實現要點
事件監聽
【說明】:
在Canvas中檢測鼠標事件是非常簡單的,可以在canvas中添加一個事件監聽器,當事件發生時,瀏覽器就會調用這個監聽器。
我們可以使用綁定事件屬性:
canvas.onmousedown = function(e) { //..... }
此外,也可以使用更為通用的addEventListener()方法來註冊監聽器:
canvas.addEventListener(‘mousedown‘,function(e){ //..... })
註意:使用onmouseXXX更為簡單,但是addEventListener()可以向某個事件註冊多個監聽器。
鼠標坐標轉換為canvas坐標
【說明】
瀏覽器通過事件對象傳遞給監聽器的鼠標坐標,是窗口坐標,而不是相對於canvas自身的坐標。大部分情況下,我們需要知道的是發生鼠標事件的點相對於canvas的位置,而不是在整個窗口中的坐標,所以必須進行坐標轉換。
【實例】:轉換代碼
function windowToCanvas(x, y) { var bbox = canvas.getBoundingClientRect(); return { x: (x - bbox.left)*(canvas.width / bbox.width), y: (y - bbox.top)*(canvas.height / bbox.height) }; }
註意:為什麽最後要乘(canvas.width / bbox.width),我們簡單說明一下,canvas存在元素大小與繪圖表面大小兩套尺寸,我們的圖像是顯示在繪圖表面上的,但是如果canvas元素大小較大的話,瀏覽器就會對繪圖表面上的圖像進行縮放以適應canvas元素大小,我們要避免這種縮放就要除去縮放比例。
我們用element表示canvas元素,用canvas表示繪圖表面,src表示繪制的內容,dest表示展示的內容
縮放規則為:dest.size = src.size * (element.size / canvas.size)
所以,src=dest.size*(canvas.size/element.size)
繪制表面的保存與恢復
【說明】:
使用getImageData與putImageData方法來保存與恢復繪圖環境的繪圖表面數據。
【實例】:保存和恢復數據
function saveDrawingSurface() { drawingSurfaceImageData = context.getImageData(0, 0, canvas.width, canvas.height); } function restoreDrawingSurface() { context.putImageData(drawingSurfaceImageData, 0, 0); }
實現代碼
<canvas id="canvas"></canvas> <div id="controls"> <select id="strokeStyleSelect"> <option value="red">red</option> <option value="green">green</option> <option value="blue">blue</option> </select> </div> GuideWires: <input id="guidewireCheckbox" type="checkbox" checked> <input id="eraseAllButton" type="button" value="Erase All"> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var context = canvas.getContext(‘2d‘); var eraseAllButton = document.getElementById("eraseAllButton"); var strokeStyleSelect = document.getElementById("strokeStyleSelect"); var guidewireCheckbox = document.getElementById("guidewireCheckbox"); var drawingSurfaceImageData; var mousedown = {}; var rubberbandrect = {}; var dragging = false; guidewires = guidewireCheckbox.checked; function windowToCanvas(x, y) { var bbox = canvas.getBoundingClientRect(); return { x: (x - bbox.left)* (canvas.width / bbox.width), y: (y - bbox.top)* (canvas.height / bbox.height) }; } function saveDrawingSurface() { drawingSurfaceImageData = context.getImageData(0, 0, canvas.width, canvas.height); } function restoreDrawingSurface() { context.putImageData(drawingSurfaceImageData, 0, 0); } function updateRubberbandRectangle(loc) { rubberbandrect.width = Math.abs(loc.x - mousedown.x); rubberbandrect.height = Math.abs(loc.y - mousedown.y); if (loc.x > mousedown.x) rubberbandrect.left = mousedown.x; else rubberbandrect.left = loc.x; if (loc.y > mousedown.y) rubberbandrect.top = mousedown.y; else rubberbandrect.top = loc.y; } function drawRubberbandShape(loc) { context.beginPath(); context.moveTo(mousedown.x, mousedown.y); context.lineTo(loc.x, loc.y); context.stroke(); } function updateRubberband(loc) { updateRubberbandRectangle(loc); drawRubberbandShape(loc); } canvas.onmousedown = function (e) { var loc = windowToCanvas(e.clientX, e.clientY); e.preventDefault(); saveDrawingSurface(); mousedown.x = loc.x; mousedown.y = loc.y; dragging = true; }; canvas.onmousemove = function (e) { var loc; if (dragging) { e.preventDefault(); loc = windowToCanvas(e.clientX, e.clientY); restoreDrawingSurface(); updateRubberband(loc); } }; canvas.onmouseup = function (e) { loc = windowToCanvas(e.clientX, e.clientY); restoreDrawingSurface(); updateRubberband(loc); dragging = false; }; context.strokeStyle = "red"; </script>
Canvas:橡皮筋線條繪制