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>

最新文章

  1. 走进缓存的世界(三) - Memcache
  2. [jquery]显示隐藏div标签的几种方法
  3. py2exe使用方法
  4. 如何使用Math对象快速计算数组中的最大值或最小值
  5. du: fts_read 失败: 无法分配内存
  6. springMVC 上传文件
  7. 论职务犯罪案件侦查 z
  8. 正宗PC Unix实验环境
  9. 320. Generalized Abbreviation
  10. VS2010 Command Prompt Error:Cannot determine the location of the VS Common Tools folder
  11. List subList()的一个demo
  12. GitBook配置
  13. bzoj 3879 虚树
  14. 配置nginx脚本开机自启动
  15. css隐藏文字的小技巧
  16. 位图索引(Bitmap Index)的故事
  17. RxJava操作符(03-变换操作)
  18. MyBatis模糊查询不报错但查不出数据的一种解决方案
  19. Selenium: Trying to log in with cookies and get the errorMessage - “Can only set cookies for current domain” or &quot;Unable to set Cookie&quot;
  20. R8500 MPv2 版本 刷 Kong编译的 ddwrt 后,使用Entware-ng 安装opkg安装第三方软件

热门文章

  1. javascript对下拉列表框(select)的操作
  2. URL编码,空格和+
  3. Openstack(Kilo)安装系列之glance(六)
  4. jqgrid的排序问题
  5. 20个JS 小技巧超级实用
  6. redhat ent6.5使用centos yum
  7. library和libraryTarget使用场景组件开发
  8. C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)
  9. 你一定喜欢看的 Webpack 2.&#215; 入门实战
  10. 总结 一下UML 类图的关系