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

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

隔江千里

自己看源代碼不就好了和我想得一樣,就是循環判斷,比大小確定範圍,直到找到爲止。想要實現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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript