为了账号安全,请及时绑定邮箱和手机立即绑定

Canvas 内部元素如何实现 mouseover/mousemove 事件?

Canvas 内部元素如何实现 mouseover/mousemove 事件?

一只萌萌小番薯 2019-04-16 20:27:39
我在使用Collie引擎来开发一个简单的游戏,它提供了mousedown、mouseup、click这三个鼠标事件,但是我想实现的功能是:当我的鼠标移到元素上的时候,显示该元素的名字。但这个引擎并没有提供mouseover或mousemove事件。Canvas是不是只能通过获取指针在画面上的坐标,然后判断是否在元素的范围,来模拟这个事件?如果是的话,有什么好的算法,用来判断指针是否在x、y、width、height(或者是圆型x、y、radius)范围中?如果不是的话,应该怎么做呢?
查看完整描述

2 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

自己看源代碼不就好了
和我想得一樣,就是循環判斷,比大小確定範圍,直到找到爲止。
想要實現mouseover啥的,自己照着_fireEvent調用_getTargetOnHitEvent即可
/**
*레이어에서이벤트가일어났을때표시객체에이벤트를발생시킨다
*
*@param{Object}e이벤트원본
*@param{String}sType이벤트타입,mouse이벤트로변형되서들어온다
*@param{Number}nX이벤트가일어난상대좌표
*@param{Number}nY이벤트가일어난상대좌표
*@return{Boolean}표시객체에이벤트가발생했는지여부
*@private
*/
_fireEvent:function(e,sType,nX,nY){
varoDisplayObject=null;
varbIsNotStoppedBubbling=true;
//캔버스에서이전레이어에객체에이벤트가일어났으면다음레이어의객체에전달되지않는다
if(sType!=="mousemove"&&!collie.Renderer.isStopEvent(sType)){
varaDisplayObjects=this._oLayer.getChildren();
oDisplayObject=this._getTargetOnHitEvent(aDisplayObjects,nX,nY);
//mousedown일경우객체를저장한다
if(oDisplayObject){
bIsNotStoppedBubbling=this._bubbleEvent(oDisplayObject,sType,e,nX,nY);
if(sType==="mousedown"){
this._setMousedownObject(oDisplayObject);
}
if(sType==="mouseup"){
this._unsetMousedownObject(oDisplayObject);
}
}
}
//mouseup처리가안된경우임의발생
if(sType==="mouseup"&&this._getMousedownObject()!==null){
oDisplayObject=this._getMousedownObject();
this._bubbleEvent(oDisplayObject,sType,e,nX,nY);
this._unsetMousedownObject(oDisplayObject);
}
/**
*click이벤트,모바일환경일때는touchstart,touchend를비교해서좌표가일정이내로움직였을경우click이벤트를발생한다d
*@namecollie.Layer#click
*@event
*@param{Object}htEvent
*@param{collie.DisplayObject}htEvent.displayObject대상객체
*@param{HTMLEvent}htEvent.event이벤트객체
*@param{Number}htEvent.x상대x좌표
*@param{Number}htEvent.y상대y좌표
*/
/**
*mousedown이벤트,모바일환경일때는touchstart이벤트도해당된다.
*@namecollie.Layer#mousedown
*@event
*@param{Object}htEvent
*@param{collie.DisplayObject}htEvent.displayObject대상객체
*@param{HTMLEvent}htEvent.event이벤트객체
*@param{Number}htEvent.x상대x좌표
*@param{Number}htEvent.y상대y좌표
*/
/**
*mouseup이벤트,모바일환경일때는touchend이벤트도해당된다.
*@namecollie.Layer#mouseup
*@event
*@param{Object}htEvent
*@param{collie.DisplayObject}htEvent.displayObject대상객체
*@param{HTMLEvent}htEvent.event이벤트객체
*@param{Number}htEvent.x상대x좌표
*@param{Number}htEvent.y상대y좌표
*/
/**
*mousemove이벤트,모바일환경일때는touchmove이벤트도해당된다.
*@namecollie.Layer#mouseup
*@event
*@param{Object}htEvent
*@param{collie.DisplayObject}htEvent.displayObject대상객체
*@param{HTMLEvent}htEvent.event이벤트객체
*@param{Number}htEvent.x상대x좌표
*@param{Number}htEvent.y상대y좌표
*/
if(bIsNotStoppedBubbling){//stop되면Layer이벤트도일어나지않는다
this._oLayer.fireEvent(sType,{
event:e,
displayObject:oDisplayObject,
x:nX,
y:nY
});
}
return!!oDisplayObject;
},
/**
*이벤트대상을고른다
*-가장위에있는대상이선정되어야한다
*@private
*@param{Array|collie.DisplayObject}vDisplayObject
*@param{Number}nX이벤트상대x좌표
*@param{Number}nY이벤트상대y좌표
*@return{collie.DisplayObject|Boolean}
*/
_getTargetOnHitEvent:function(vDisplayObject,nX,nY){
varoTargetObject=null;
if(vDisplayObjectinstanceofArray){
for(vari=vDisplayObject.length-1;i>=0;i--){
//자식부터
if(vDisplayObject[i].hasChild()){
oTargetObject=this._getTargetOnHitEvent(vDisplayObject[i].getChildren(),nX,nY);
//찾았으면멈춤
if(oTargetObject){
returnoTargetObject;
}
}
//본인도
oTargetObject=this._getTargetOnHitEvent(vDisplayObject[i],nX,nY);
//찾았으면멈춤
if(oTargetObject){
returnoTargetObject;
}
}
}else{
returnthis._isPointInDisplayObjectBoundary(vDisplayObject,nX,nY)?vDisplayObject:false;
}
},
/**
*DisplayObject범위안에PointX,PointY가들어가는지확인
*
*@private
*@param{collie.DisplayObject}oDisplayObject
*@param{Number}nPointX확인할포인트X좌표
*@param{Number}nPointY확인할포인트Y좌표
*@return{Boolean}들어간다면true
*/
_isPointInDisplayObjectBoundary:function(oDisplayObject,nPointX,nPointY){
//안보이는상태거나이벤트를받지않는다면지나감
if(
!oDisplayObject._htOption.useEvent||
!oDisplayObject._htOption.visible||
!oDisplayObject._htOption.width||
!oDisplayObject._htOption.height||
(oDisplayObject._htOption.useEvent==="auto"&&!oDisplayObject.hasAttachedHandler())
){
returnfalse;
}
varhtHitArea=oDisplayObject.getHitAreaBoundary();
//영역안에들어왔을경우
if(
htHitArea.left<=nPointX&&nPointX<=htHitArea.right&&
htHitArea.top<=nPointY&&nPointY<=htHitArea.bottom
){
//hitArea설정이없으면사각영역으로체크
if(!oDisplayObject._htOption.hitArea){
returntrue;
}else{
varhtPos=oDisplayObject.getRelatedPosition();
//대상Point를상대좌표로변경
nPointX-=htPos.x;
nPointY-=htPos.y;
//transform적용
varaHitArea=oDisplayObject._htOption.hitArea;
aHitArea=collie.Transform.points(oDisplayObject,aHitArea);
returnthis._isPointInPolygon(aHitArea,nPointX,nPointY);
}
}
returnfalse;
},
                            
查看完整回答
反对 回复 2019-04-16
  • 2 回答
  • 0 关注
  • 1220 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信