這裏是解決這個的一種方法:
因爲我們需要知道我們需要兩個標誌(有些人喜歡的對象兩種狀態 - 它是由你):
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>
來源
2016-05-15 15:53:50
K3N
發佈您的事件處理程序和樣品HTML。閱讀[mcve] – yezzz
嘗試使用mousedown事件進行選擇而不是單擊。 – ShuberFu