HTML5画布:在画布之外拖动 [英] HTML5 Canvas: Dragging outside of canvas

查看:183
本文介绍了HTML5画布:在画布之外拖动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了使用HTML5 Canvas实现拖动功能的问题。我理解缺少场景图形等,并且已经设置了一种方法来识别鼠标事件拖动一个矩形。



但是:问题是丢失鼠标事件鼠标离开画布。如果我拖到画布外面并释放鼠标按钮,我的代码不会得到一个mouseup事件相应地改变拖动逻辑。然后拖动的对象仍然粘在我的鼠标上,直到我再次开始拖动。



fabric.js 没有这个问题,但我无法识别库中的相关代码。

解决方案

首先使用布尔变量isMouseDragged,在mouseDown后设置为true,在mouseUp我会在稍后解释)



您可以处理拖曳的几种方式。

  if(mouse ['isMouseDragged']){
mouse ['xUp'] = e.clientX - canvas.getBoundingClientRect()。left;
mouse ['yUp'] = e.clientY - canvas.getBoundingClientRect()。top;
...




  1. 在你按下和释放按钮的点之间的交叉点(想象它为线)和画布的边缘,超过它是鼠标指针(想象它作为另一条线)。将mouseUp位置作为这两行的交集。

      //第一个选项
    if(mouse ['mode'] =鼠标['xDown'],鼠标['yDown'],鼠标['xDown'],鼠标['XYZ] 'xUp'],mouse ['yUp']);
    mouse ['xUp'] = edgeIntersect ['x'];
    mouse ['yUp'] = edgeIntersect ['y'];保持您的虚拟鼠标指针(坐标),然后单击鼠标左键,然后选择

      //第二个选项
    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'];
    }
    }


  2. 在坐着OnMouseUp

      //第三选项
    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)* ) - (x4-x3)*(y2-y1)))*(x2-x1));
thisY = Math.round(y1 +((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/(y4-y3)* ) - (x4-x3)*(y2-y1)))*(y2-y1));

//我必须为其他检查,否则角落(当两个条件为真时)无法处理
//所以我会一个接一个地处理
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)* ) - (x4-x3)*(y2-y1)))*(x2-x1));
thisY = Math.round(y1 +((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/(y4-y3)* ) - (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)* ) - (x4-x3)*(y2-y1)))*(x2-x1));
thisY = Math.round(y1 +((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/(y4-y3)* ) - (x4-x3)*(y2-y1)))*(y2-y1));
x2 = ThisX;
y2 = thisY;
}

if(y2> canvas.height - 1){//底边
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)* ) - (x4-x3)*(y2-y1)))*(x2-x1));
thisY = Math.round(y1 +((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/(y4-y3)* ) - (x4-x3)*(y2-y1)))*(y2-y1));
}

return {
'x':thisX,
'y':thisY
};

}



http://jsfiddle.net/WolfeSVK/s2tNr/


I am having issues implementing dragging functionality with HTML5 Canvas. I understand the lack of a scene graph etc., and have set up a way to identify drag a rectangle on mouse events.

However: the problem is losing mouse events when the mouse leaves the Canvas. If I drag outside of the canvas and release the mouse button, my code doesn't get a mouseup event to alter the dragging logic accordingly. The dragged object then remains stuck to my mouse until I start dragging again.

fabric.js doesn't have this problem, but I can't identify the relevant code in the library. How does it do this?

解决方案

First use boolean variable isMouseDragged which is set true after mouseDown and false after mouseUp (or another event I'll explain later)

You can handle dragging several ways.

if (mouse['isMouseDragged']) {
   mouse['xUp'] = e.clientX - canvas.getBoundingClientRect().left;
   mouse['yUp'] = e.clientY - canvas.getBoundingClientRect().top;
   ...

  1. On mouse up calculate intersection between point where you pressed and released button (imagine it as line) and edge of canvas beyond which is mouse pointer (imagine it as another line). Put mouseUp position as intersection of these two lines.

    // 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'];
        }
    }
    

  2. Hold your virtual mouse pointer (coordinates) inside a canvas.

    // 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'];
        }
    }
    

  3. Make coordinates onMouseUp = onMouseOut as you go out of canvas and set isMouseDragged false.

    // THIRD OPTION
    if (mouse['isMouseDragged']) {
       if (mouse['mode'] == mouse['MOUSEOUT_POS']) {
          mouse['xUp'] = mouse['xOut'];
          mouse['yUp'] = mouse['yOut'];
          mouse['isMouseDragged'] = false;
       }
    }
    

To calculate an intersect on edge of the canvas:

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
};

}

Look at the source code: http://jsfiddle.net/WolfeSVK/s2tNr/

这篇关于HTML5画布:在画布之外拖动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆