不规则图片点击识别
众所周知,图片都是矩形的,但是有些图片是一个美女,一只猫or狗,这时候,我们希望可以把美女,带到我们的黄金屋去,噼里啪啦,搞定!
找不到美女,找到了一头狼
嗯,可以移动了,可是,图片是矩形的,点击矩形的透明区域,图片也跟着移动了,在用户眼中,他们才不管你的是矩形圆形,他们要的是效果:
所以,需要判断图片的不规则区域,触摸的是该区域,才移动,我们再次拖动图片的透明区域,灰太狼是不动的,这里我们用到了一个getImageData
去获取canvas
点击处的像素,以判断该处是否透明,官方文档如下:
所以,我们在触摸事件中加如入代码:
var imgData = this.myctx.getImageData(x,y, 1, 1);
var alpha = imgData.data[3];
this.myctx.needMove = alpha > 0;
根据needMove
判断是否移动,部分代码如下index-canvas.html
:
function touchLister(event) {
var event = event || window.event;
switch(event.type) {
case "touchstart":
var touchEvent = event.changedTouches[0];
var offsetLeft = event.target.offsetLeft;
var offsetTop = event.target.offsetTop;
this.myctx.startX = touchEvent.pageX - offsetLeft;
this.myctx.startY = touchEvent.pageY - offsetTop;
var x = parseInt(touchEvent.pageX - offsetLeft),
y = parseInt(touchEvent.pageY - offsetTop);
var imgData = this.myctx.getImageData(x,y, 1, 1);
var alpha = imgData.data[3];
this.myctx.needMove = alpha > 0;
break;
case "touchmove":
if (this.myctx.needMove){
this.style.left = (event.changedTouches[0].pageX - this.myctx.startX) + 'px';
this.style.top = (event.changedTouches[0].pageY - this.myctx.startY) + 'px';
}
event.preventDefault();
break;
case "touchend":
break;
}
}
图片的重叠问题
当界面上的不规则图形 > 1 的时候,以上图为例,我们想要拖动在狼后面的羊,由于有一部分被狼图片的透明部分所挡住,当我们想要拖动羊而恰好拖动的触摸点在这部分的范围内时,是无法拖动后面的羊,当然,你可以这么做:
- 整体使用一个
canvas
,记录每个图片的信息,然后不断的重绘,遇到羊和狼重叠的部分,需要先判断是否点击处的坐标是否是在狼身上,还是在狼的透明区域上,若在透明区域上,需要再判断是在羊身上,还是在羊透明区域上,若在羊身上,移动羊 - 使用轮子,好吧,站在巨人的肩膀上再走一回,谁让咱懒捏
该部分代码见demo(index-canvas.html)
使用动画库collie
collie
是一个 JavaScript 库,用于为移动平台创建优化的动画和游戏
使用collie加载一只狼
oLayer = new collie.Layer({
width: clientWidth,
height: clientHeight
});
//加载图片
collie.ImageManager.add('img1', 'img/pic1.png');
new collie.DisplayObject({
width: 302,
height: 316,
x: 0,
y: 0,
backgroundImage: 'imgs1'
}).addTo(oLayer);
Layer
是一个容器,可以在里面放图片对象DisplayObject
,以上代码效果如下:
狼太大了,需要进行缩放,将大小变为原来的一半
new collie.DisplayObject({
width: 302,
height: 316,
x: 0,
y: 0,
backgroundImage: 'imgs1',
originX: 'left',
originY: 'top',//1
scaleX: 0.5,
scaleY: 0.5,
}).addTo(oLayer);
1.任何一个元素都有一个中心点,默认情况之下,其中心点是居于元素X轴和Y轴的50%处,不改变该点情况下,进行的旋转、位移、缩放,扭曲等操作都是以元素自己中心位置进行变形,此处将该点改为左上角,效果见下图
让狼动起来
new collie.DisplayObject({
width: 302,
height: 316,
x: 0,
y: 0,
backgroundImage: 'imgs1',
originX: 'left',
originY: 'top',
scaleX: 0.5,
scaleY: 0.5,
useEvent: true//1
}).addTo(oLayer);
oLayer.attach({
mousedown: function(oEvent) {
if(oEvent.displayObject) {
oSelectedDisplayObject = oEvent.displayObject;
htStartPosition = {
x: oEvent.x,
y: oEvent.y
};
htSelectedDisplayObjectPosition = {
x: oSelectedDisplayObject.get("x"),
y: oSelectedDisplayObject.get("y")
};//2
}
},
mouseup: function(oEvent) {
if(oSelectedDisplayObject !== null) {
oSelectedDisplayObject = null;
htSelectedDisplayObjectPosition = htStartPosition = {};
}
},
mousemove: function(oEvent) {
if(oSelectedDisplayObject !== null) {
var x = htStartPosition.x - oEvent.x;
var y = htStartPosition.y - oEvent.y;
oSelectedDisplayObject.set({
x: htSelectedDisplayObjectPosition.x - x,
y: htSelectedDisplayObjectPosition.y - y
});//3
}
}
});
1.设置图片对象响应事件
2.记录鼠标按下时的坐标,当前图片的x,y
3.根据上一步记录的坐标和当前的坐标的差值,可以知道移动了多少,相应的让图片也移动这个差值,实现拖动效果
区域拖动
狼的拖动已经实现了,但是又回到了一开始的问题,不规则点击识别,collie
已经给我们考虑到了,collie.DisplayObject
有一个参数hitArea
,官方文档:
可以设置某个区域响应事件,如下图:
红色圈起来的为可响应区域,该区域由一些点组成,collie
很贴心的提供了工具供我们生成这些点,传送门,代码:
hitArea: [
[[x1,y1],[x2,y2]]
]
运行效果如下:
区域拖动实现了,但是仔细观察会发现,大灰狼会越界,超出黄色的范围,对此,可以设置collie.DisplayObject
的rangeX
和rangeY
,文档:
rangeX: [0, clientWidth - sizes[i][0] * scale],
rangeY: [0, clientHeight - sizes[i][1] * scale],
设置了范围之后,可以防止超出黄色区域
加多点动物
这里在按下事件中,将选中的displayObject
移除,重新添加,实现了被选中的动物移动最前面:
mousedown: function(oEvent) {
if(oEvent.displayObject) {
oSelectedDisplayObject = oEvent.displayObject;
htStartPosition = {
x: oEvent.x,
y: oEvent.y
};
htSelectedDisplayObjectPosition = {
x: oSelectedDisplayObject.get("x"),
y: oSelectedDisplayObject.get("y")
};
oLayer.removeChild(oEvent.displayObject);
oLayer.addChild(oEvent.displayObject);
}
},
至此,对于上面的图片重叠问题,也算是解决啦!该部分代码见demo(index-collie.html)