我在使用 Collie 引擎 来开发一个简单的游戏,它提供了 mousedown、mouseup、click 这三个鼠标事件,但是我想实现的功能是:当我的鼠标移到元素上的时候,显示该元素的名字。但这个引擎并没有提供 mouseover 或 mousemove 事件。

Canvas 是不是只能通过获取指针在画面上的坐标,然后判断是否在元素的范围,来模拟这个事件?

如果是的话,有什么好的算法,用来判断指针是否在 x、y、width、height (或者是圆型 x、y、radius) 范围中?

如果不是的话,应该怎么做呢?

回答

自己看源代碼不就好了

和我想得一樣,就是循環判斷,比大小確定範圍,直到找到爲止。

想要實現 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) { var oDisplayObject = null; var bIsNotStoppedBubbling = true; // 캔버스에서 이전 레이어에 객체에 이벤트가 일어났으면 다음 레이어의 객체에 전달되지 않는다
if (sType !== "mousemove" && !collie.Renderer.isStopEvent(sType)) { var aDisplayObjects = 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
* @name collie.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 이벤트도 해당 된다.
* @name collie.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 이벤트도 해당 된다.
* @name collie.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 이벤트도 해당 된다.
* @name collie.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) { var oTargetObject = null; if (vDisplayObject instanceof Array) { for (var i = vDisplayObject.length - 1; i >= 0; i--) { // 자식부터
if (vDisplayObject[i].hasChild()) {
oTargetObject = this._getTargetOnHitEvent(vDisplayObject[i].getChildren(), nX, nY); // 찾았으면 멈춤
if (oTargetObject) { return oTargetObject;
}
} // 본인도
oTargetObject = this._getTargetOnHitEvent(vDisplayObject[i], nX, nY); // 찾았으면 멈춤
if (oTargetObject) { return oTargetObject;
}
}
} else { return this._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())
) { return false;
} var htHitArea = oDisplayObject.getHitAreaBoundary(); // 영역 안에 들어왔을 경우
if (
htHitArea.left <= nPointX && nPointX <= htHitArea.right &&
htHitArea.top <= nPointY && nPointY <= htHitArea.bottom
) { // hitArea 설정이 없으면 사각 영역으로 체크
if (!oDisplayObject._htOption.hitArea) { return true;
} else { var htPos = oDisplayObject.getRelatedPosition(); // 대상 Point를 상대 좌표로 변경
nPointX -= htPos.x;
nPointY -= htPos.y; // transform 적용
var aHitArea = oDisplayObject._htOption.hitArea;
aHitArea = collie.Transform.points(oDisplayObject, aHitArea); return this._isPointInPolygon(aHitArea, nPointX, nPointY);
}
} return false;
},

使用 addEventListener() 监听事件,并执行QQ号码买卖地图相应函数

canvas.addEventListener('mousemove',mouseMove,false); //监听鼠标移动canvas.addEventListener('mousedown',mouseDown,false); //监听鼠标按下canvas.addEventListener('mouseup',mouseUp,false); //监听鼠标松开canvas.addEventListener('mouseout',mouseUp,false); //监听鼠标离开canvas.addEventListener('dblclick',doubleClick,false); //监听鼠标双击


更多相关文章

  1. 【前端】添加draggable 属性,无论怎么设置都无法触发dragstart后
  2. js事件,线程,定时器
  3. Vue一个通用的组件传递点击事件的两种种简单方法
  4. 轮播图自动翻页功能实现
  5. 事件的添加方式
  6. 表单元素及表单事件
  7. JS执行机制、事件模型、表单事件、事件冒泡、fetch的常用场景
  8. 任务队列、事件、冒泡、fetch使用
  9. JavaScript onblur与onfocus事件详解

随机推荐

  1. 访问 Android 开发者网站 & Go 官网的 ti
  2. Android(安卓)Toast带图标水平布局的简单
  3. Android权限问题 及 APP应用图标
  4. Android使用TextView实现跑马灯效果
  5. 解决:Android中 Error generating final a
  6. Android(安卓)Studio无线调试app之Androi
  7. 配置新的product(译)——android编译系统
  8. android中的线程池
  9. 收藏Android下bitmap内存限制OUT OF MEMO
  10. ADT在线安装(http://dl-ssl.google.com/an