如何实现Canvas图像的拖拽、点击等操作
2014-07-09 11:19
309 查看
上一篇Canvas的博文写完后,有位朋友希望能对Canvas绘制出来的图像进行点击、拖拽等操作,因为Canvas绘制出的图像能很好的美化。好像是想做炉石什么的游戏,我也没玩过。
Canvas在我的理解中就好像在一张画布上绘制图像,它只能看到却“摸”不到,那要如何进行操作呢。我不知道网上是怎么做的,这里用自己的想法做了个DEMO分享给大家。
思路:
虽然Canvas不能拖拽,但div可以拖拽,那怎么把二者结合起来呢。初步想法是将一个与Canvas图像大小差不多的div覆盖在其上,在拖拽div时将获取的光标坐标修正后传给Canvas绘制函数并刷新图像的位置。
既然要覆盖,先做些准备工作:
1.将div与Canvas画布均position:absolute,否则无法重叠。
2.将div的z-index值设置大点,保证其在Canvas画面之上。
准备工作完成后,我们先来看div的拖拽:
来解读下这段代码:首先获取div对象,设置拖拽标志moveFlage,当onmousedown时为true表示可以拖动,当onmouseup时为false表示不能拖动了。
这三行代码是为了修正光标位置。当点击时,记录下光标在div上的位置。mwidth和mheight表示光标落点相对于div左边和上边的距离。如果不加修正:
这就是不加修正的结果,当光标点下时,div的坐标即左上角会与光标坐标一致。
修正后:
点击时光标总会“粘”在div某点上。
接下来绘制图片:
首先定义全局变量X和Y,它们是为了实时更新图像的绘制坐标。
获取“画笔”,获取图片对象。这里setInterval循环执行绘制图片的函数,以刷新图片的位置,setInterval的间隔值越小,拖拽起来越“流畅”。
同时别忘了clearRect,当图片移动到下一个位置时,清除上一个位置的图片,参数为Canvas画布的坐标和尺寸。
在拖拽时将修正后的光标坐标传给X、Y:
最后加上div和图像的活动范围:
这个就看个人的要求了,注意是要同时限定div和图片的活动范围。1000与500为本例的画布大小,如果是在整个页面里活动就换成innerWidth或innerHeight。
彻底隐藏div看看效果:
最后说下点击事件,这里要注意的是在拖拽的过程中onmousedown与onmouseup二者就构成了一个click过程,但我们不希望在拖拽结束后触发点击事件。
这里有个比较简单的办法,定义一个clickFlag默认为false,当onmousedown时设为true,若进行了onmousemove事件时设为false。
在最后onmouseup时判断clickFlag的值,为true时才触发点击事件。也就是说当你按下鼠标时,只有不发现移动,松开鼠标时才会触发点击事件。
整理后的JS代码:
本例到此结束,更多功能大家有兴趣可以自己开发,感谢您的浏览,也感谢每个对我这菜鸟提意见的人。
Canvas在我的理解中就好像在一张画布上绘制图像,它只能看到却“摸”不到,那要如何进行操作呢。我不知道网上是怎么做的,这里用自己的想法做了个DEMO分享给大家。
思路:
虽然Canvas不能拖拽,但div可以拖拽,那怎么把二者结合起来呢。初步想法是将一个与Canvas图像大小差不多的div覆盖在其上,在拖拽div时将获取的光标坐标修正后传给Canvas绘制函数并刷新图像的位置。
既然要覆盖,先做些准备工作:
1.将div与Canvas画布均position:absolute,否则无法重叠。
2.将div的z-index值设置大点,保证其在Canvas画面之上。
准备工作完成后,我们先来看div的拖拽:
var divObj=document.getElementById("cover"); var moveFlag=false; divObj.onmousedown=function(e){ moveFlag=true; var clickEvent=window.event||e; var mwidth=clickEvent.clientX-divObj.offsetLeft; var mheight=clickEvent.clientY-divObj.offsetTop; document.onmousemove=function(e){ var moveEvent=window.event||e; if(moveFlag){ divObj.style.left=moveEvent.clientX-mwidth+"px"; divObj.style.top=moveEvent.clientY-mheight+"px"; divObj.onmouseup=function(){ moveFlag=false; } } } };
来解读下这段代码:首先获取div对象,设置拖拽标志moveFlage,当onmousedown时为true表示可以拖动,当onmouseup时为false表示不能拖动了。
var clickEvent=window.event||e; var mwidth=clickEvent.clientX-divObj.offsetLeft; var mheight=clickEvent.clientY-divObj.offsetTop;
这三行代码是为了修正光标位置。当点击时,记录下光标在div上的位置。mwidth和mheight表示光标落点相对于div左边和上边的距离。如果不加修正:
这就是不加修正的结果,当光标点下时,div的坐标即左上角会与光标坐标一致。
修正后:
点击时光标总会“粘”在div某点上。
接下来绘制图片:
首先定义全局变量X和Y,它们是为了实时更新图像的绘制坐标。
var ctx=document.getElementById("myCanvas").getContext("2d"); var img=document.getElementById("myImg"); function drawImg(){ ctx.clearRect(0,0,1000,500); ctx.beginPath(); ctx.drawImage(img,X,Y); ctx.closePath(); ctx.stroke(); } window.onload=function(){ setInterval(drawImg,1); }
获取“画笔”,获取图片对象。这里setInterval循环执行绘制图片的函数,以刷新图片的位置,setInterval的间隔值越小,拖拽起来越“流畅”。
同时别忘了clearRect,当图片移动到下一个位置时,清除上一个位置的图片,参数为Canvas画布的坐标和尺寸。
在拖拽时将修正后的光标坐标传给X、Y:
X=moveEvent.clientX-mwidth; Y=moveEvent.clientY-mheight;
最后加上div和图像的活动范围:
if(moveEvent.clientX<=mwidth){ divObj.style.left=0+"px"; X=0; } if(parseInt(divObj.style.left)+divObj.offsetWidth >=1000){ divObj.style.left=1000 - divObj.offsetWidth+"px"; X=1000 - divObj.offsetWidth; } if(moveEvent.clientY<=mheight){ divObj.style.top=0+"px"; Y=0; } if(parseInt(divObj.style.top)+divObj.offsetHeight>=500){ divObj.style.top=500-divObj.offsetHeight+"px"; Y=500-divObj.offsetHeight; }
这个就看个人的要求了,注意是要同时限定div和图片的活动范围。1000与500为本例的画布大小,如果是在整个页面里活动就换成innerWidth或innerHeight。
彻底隐藏div看看效果:
最后说下点击事件,这里要注意的是在拖拽的过程中onmousedown与onmouseup二者就构成了一个click过程,但我们不希望在拖拽结束后触发点击事件。
这里有个比较简单的办法,定义一个clickFlag默认为false,当onmousedown时设为true,若进行了onmousemove事件时设为false。
在最后onmouseup时判断clickFlag的值,为true时才触发点击事件。也就是说当你按下鼠标时,只有不发现移动,松开鼠标时才会触发点击事件。
整理后的JS代码:
// 绘制图片坐标
var X=0;
var Y=0;
// js部分
var divObj=document.getElementById("cover");
var moveFlag=false;
//区别moueseup与click的标志
var clickFlag=false;
// 拖拽函数
divObj.onmousedown=function(e){
moveFlag=true;
clickFlag=true;
var clickEvent=window.event||e;
var mwidth=clickEvent.clientX-divObj.offsetLeft;
var mheight=clickEvent.clientY-divObj.offsetTop;
document.onmousemove=function(e){
clickFlag=false;
var moveEvent=window.event||e;
if(moveFlag){
divObj.style.left=moveEvent.clientX-mwidth+"px";
divObj.style.top=moveEvent.clientY-mheight+"px";
//// 将鼠标坐标传给Canvas中的图像
X=moveEvent.clientX-mwidth;
Y=moveEvent.clientY-mheight;
//// 下面四个条件为限制div以及图像的活动边界
if(moveEvent.clientX<=mwidth){ divObj.style.left=0+"px"; X=0; } if(parseInt(divObj.style.left)+divObj.offsetWidth >=1000){ divObj.style.left=1000 - divObj.offsetWidth+"px"; X=1000 - divObj.offsetWidth; } if(moveEvent.clientY<=mheight){ divObj.style.top=0+"px"; Y=0; } if(parseInt(divObj.style.top)+divObj.offsetHeight>=500){ divObj.style.top=500-divObj.offsetHeight+"px"; Y=500-divObj.offsetHeight; }
divObj.onmouseup=function(){
moveFlag=false;
if(clickFlag){
alert("点击生效");
}
}
}
}
};
本例到此结束,更多功能大家有兴趣可以自己开发,感谢您的浏览,也感谢每个对我这菜鸟提意见的人。
相关文章推荐
- 如何用CSS实现图像替换链接文本显示并保证链接可点击
- 【Android】人体图片、地图图片、热力图,如何实现点击不同的部位执行不同的操作?
- C# winform datagridview中如何实现鼠标右键点击一行数据出现一个带有删除的菜单,并能执行删除操作?
- HTML5新特性之Canvas+drag(拖拽图像实现图像反转)
- 最近被一个问题困扰着,如何实现类似Photoshop的多层图像操作,每层可单独操作,又可以组合显示出来。
- C#WinForm 如何实现屏蔽窗口右上角的关闭操作,点击时不关闭程序
- js是如何实现拖拽raphael.js所绘制图像的
- <canvas>+JS如何实现可拖拽并且显示百分比的环形进度条
- android中如何实现进入一个界面不做任何动作过10秒钟(有操作从新计时)自动跳转到待机activity,点击待机界面回到原来的界面
- HTML5新特性之Canvas+drag(拖拽图像实现图像反转)
- Canvas如何实现图像的居中、平铺效果
- 在WPF中如何实现列表控件的拖拽操作
- 几种常见计算机图像处理操作的原理及canvas实现
- 小程序中如何实现操作菜单的显示(点击选取图片,弹出菜单拍摄、相册)功能
- dbgrideh如何实现点击标题排序
- ★ 如何利用TWAIN实现对光栅图像输入设备(扫描仪、数码相机...)的程序设计(1) ---孙涛---
- 在ASP.NET中如何实现拖拽和停靠?
- 市面上所有号称"虚拟机","防火墙"的实时监控杀毒软件无一不是使用的IFSHOOK技术.但是同时也有一些朋友不断写MAIL给我打听如何实现读写的监控.下面给出用VTOOLSD写的代码.也就是所有实时杀毒软件的奥秘.同时,很多拦截文件操作的软件,例如对目录加
- 鼠标在slide控件的任意位置上点击,滑块滑动到该位置是如何实现的,有什么属性吗?
- 如何实现SQL Server数据库操作中的异常捕捉和处理