Canvas:橡皮筋线条绘制
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> <script> var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var drawingSufraceData; var mousedown ={}; var dragging = false; //绝对坐标转相对坐标 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() { drawingSufraceData = context.getImageData(0,0,canvas.width,canvas.height); } function restoreDrawingSurface() { context.putImageData(drawingSufraceData,0,0); } function drawingLine(loc) { context.beginPath(); context.moveTo(mousedown.x,mousedown.y); context.lineTo(loc.x,loc.y); context.stroke() } //鼠标按下 canvas.onmousedown = function (e) { mousedown = windowToCanvas(e.x,e.y); saveDrawingSurface(); dragging =true; } //鼠标移动 canvas.onmousemove = function (e) { var loc = windowToCanvas(e.x,e.y); if(dragging) { restoreDrawingSurface(); drawingLine(loc); } } //鼠标松开 canvas.onmouseup =function (e) { dragging=false; } </script>