我正在尝试使用HTML 5画布编写一个简单的地图。拖动鼠标可移动地图,然后单击以选择最近的航路点。但是,有一个问题。当我拖动鼠标时,释放它时仍会获得click事件。我想仅在单击时没有移动的情况下得到此消息。
我试图在mousemove事件处理程序中检查是否有不活动事件,但没有成功:
function onMove(e) {
if(e.movementX == 0 && e.movementY == 0) {
console.log("a"); //never happens...
}
}
我的问题是:有没有简便的方法,还是应该检查新闻发布会是否在同一地点?
这是我的代码:
function onMove(e) {
console.log("moving");
}
function onClick(e) {
console.log("clicked");
}
function init() {
c = document.getElementById("MapCanvas");
ctx = c.getContext("2d");
c.addEventListener("click", onClick, true);
c.addEventListener("mousemove", onMove, true);
}
这是解决此问题的一种方法:
因为我们需要知道两个状态,所以我们需要两个标志(有些喜欢对象-由您决定):
var isDown = false; // mouse button is held down
var isMoving = false; // we're moving (dragging)
然后,我们需要找到一种方法来区分拖动和点击。一种典型的方法是使用第一个点击点到当前点之间的半径(长度):如果在外部,我们将其视为拖动操作。
所以 -
var radius = 9 * 9 // radius in pixels, 9 squared
var firstPos; // keep track of first position
(我们对9进行平方运算,因此以后不必为每个鼠标移动事件都计算平方根)。
然后,我们可以定义我们的回调处理程序以考虑以下因素:
canvas.onmousedown = function(e) {
firstPos = getXY(e); // record click position (see getXY function in demo)
isDown = true; // record mouse state
isMoving = false; // reset move state
};
可以在window
对象上设置下一个处理程序,而不是在画布元素本身上设置。这使我们可以在按住鼠标键的同时将其移动到canvas元素之外。我们需要在addEventListener()
这里使用,因此我们也允许其他代码进行订阅:
window.addEventListener("mousemove", function(e) {
if (!isDown) return; // we will only act if mouse button is down
var pos = getXY(e); // get current mouse position
// calculate distance from click point to current point
var dx = firstPos.x - pos.x,
dy = firstPos.y - pos.y,
dist = dx * dx + dy * dy; // skip square-root (see above)
if (dist >= radius) isMoving = true; // 10-4 we're on the move
if (isMoving) {
// handle move operation here
}
});
最后,我们检测到单击以及更新鼠标状态,这也在window
对象上进行:
window.addEventListener("mouseup", function(e) {
if (!isDown) return; // no need for us in this case
isDown = false; // record mouse state
if (!isMoving) {
// it was a click, handle click operation here
}
});
然后,最后的问题是单击航路点。进行绝对检查(即x ===值)很少会得到OK,因为我们需要将鼠标按钮恰好放置在该位置。使用航路点的宽度和高度(假设有一个对象wp
作为航路点)允许一个范围:
if (pos.x >= wp.x && pos.x < wp.x + wp.width &&
pos.y >= wp.y && pos.y < wp.y + wp.height) { ... }
var ctx = canvas.getContext("2d");
var wp = {x: 50, y:50, width:12, height:12}; // demo way-point
ctx.font = "20px sans-serif";
ctx.fillText("Click or click+move on this canvas...", 10, 30);
ctx.strokeRect(wp.x, wp.y, wp.width, wp.height);
var isDown = false; // mouse button is held down
var isMoving = false; // we're moving (dragging)
var radius = 9 * 9 // radius in pixels, 9 squared
var firstPos; // keep track of first position
canvas.onmousedown = function(e) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.strokeRect(wp.x, wp.y, wp.width, wp.height);
firstPos = getXY(e);
isDown = true; // record mouse state
isMoving = false; // reset move state
};
window.addEventListener("mousemove", function(e) {
if (!isDown) return; // we will only act if mouse button is down
var pos = getXY(e); // get current mouse position
// calculate distance from click point to current point
var dx = firstPos.x - pos.x,
dy = firstPos.y - pos.y,
dist = dx * dx + dy * dy; // skip square-root (see above)
if (dist >= radius) isMoving = true; // 10-4 we're on the move
if (isMoving) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.strokeRect(wp.x, wp.y, wp.width, wp.height);
ctx.fillText("MOVING", 10, 30);
}
});
window.addEventListener("mouseup", function(e) {
if (!isDown) return; // no need for us in this case
isDown = false; // record mouse state
if (!isMoving) {
if (firstPos.x >= wp.x && firstPos.x < wp.x + wp.width &&
firstPos.y >= wp.y && firstPos.y < wp.y + wp.height) {
ctx.fillText("CLICKED WAYPOINT", 10, 30);
}
else {
ctx.fillText("CLICK", 10, 30);
}
}
});
function getXY(e) {
var rect = canvas.getBoundingClientRect();
return {x: e.clientX - rect.left, y: e.clientY - rect.top}
}
canvas {background:#ccc}
<canvas id=canvas width=620 height=180></canvas>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句