最初に boolean 変数 isMouseDragged を使用します。これは、mouseDown の後に true に設定され、mouseUp の後に false に設定されます (または後で説明する別のイベント)。
ドラッグはいくつかの方法で処理できます。
if (mouse['isMouseDragged']) {
mouse['xUp'] = e.clientX - canvas.getBoundingClientRect().left;
mouse['yUp'] = e.clientY - canvas.getBoundingClientRect().top;
...
マウスアップで、ボタンを押して離したポイント (線として想像してください) と、マウス ポインターがあるキャンバスの端 (別の線として想像してください) の間の交点を計算します。これらの 2 つの線の交点として mouseUp の位置を置きます。
// FIRST OPTION
if (mouse['mode'] == mouse['INTERSECTION']) {
if (!mouse['isMouseOver']) {
var edgeIntersect = mouseDraggedOut(mouse['xDown'], mouse['yDown'], mouse['xUp'], mouse['yUp']);
mouse['xUp'] = edgeIntersect['x'];
mouse['yUp'] = edgeIntersect['y'];
}
}
キャンバス内で仮想マウス ポインター (座標) を保持します。
// SECOND OPTION
if (!mouse['isMouseOver']) {
if (mouse['mode'] == mouse['LOCK_INSIDE']) {
var edgeIntersect = mouseDraggedOut(canvas.width / 2, canvas.height / 2, mouse['x'], mouse['y']);
mouse['x'] = edgeIntersect['x'];
mouse['y'] = edgeIntersect['y'];
}
}
キャンバスの外に出るときに座標を onMouseUp = onMouseOut にして、isMouseDragged を false に設定します。
// THIRD OPTION
if (mouse['isMouseDragged']) {
if (mouse['mode'] == mouse['MOUSEOUT_POS']) {
mouse['xUp'] = mouse['xOut'];
mouse['yUp'] = mouse['yOut'];
mouse['isMouseDragged'] = false;
}
}
キャンバスのエッジの交差を計算するには:
function mouseDraggedOut(x1, y1, x2, y2) {
// x1,y1 = mouseDown; x2,y2 = mouseUp
var x3, y3, x4, y4;
var thisX, thisY;
if (x2 < 0) {// left edge
x3 = 0;
y3 = 0;
x4 = 0;
y4 = canvas.height;
thisX = Math.round(x1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (x2 - x1));
thisY = Math.round(y1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (y2 - y1));
// I must do this for other checks, else corners (when two conditions are true) couldn't be handled
// So I'll handle it one after another
x2 = thisX;
y2 = thisY;
}
if (x2 > canvas.width - 1) {// right edge
x3 = canvas.width - 1;
y3 = 0;
x4 = canvas.width - 1;
y4 = canvas.height - 1;
thisX = Math.round(x1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (x2 - x1));
thisY = Math.round(y1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (y2 - y1));
x2 = thisX;
y2 = thisY;
}
if (y2 < 0) {// top edge
x3 = 0;
y3 = 0;
x4 = canvas.width - 1;
y4 = 0;
thisX = Math.round(x1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (x2 - x1));
thisY = Math.round(y1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (y2 - y1));
x2 = thisX;
y2 = thisY;
}
if (y2 > canvas.height - 1) {// bottom edge
x3 = 0;
y3 = canvas.height - 1;
x4 = canvas.width - 1;
y4 = canvas.height - 1;
thisX = Math.round(x1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (x2 - x1));
thisY = Math.round(y1 + (((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))) * (y2 - y1));
}
return {
'x' : thisX,
'y' : thisY
};
}
ソースコードを見てください: http://jsfiddle.net/WolfeSVK/s2tNr/