简体   繁体   English

Dojo gfx:onmousemove连接到破坏形状的onmouseup吗?

[英]Dojo gfx: onmousemove connected to a shape clobbering onmouseup?

I'm trying to implement a rubber-band selection box in Dojo's gfx with Canvas as the renderer. 我正在尝试使用Canvas作为渲染器在Dojo的gfx中实现橡皮筋选择框。 My intention is to have the selection box drawn when the mouse is clicked down and dragged, then disappear once the mouse is released. 我的意图是在单击鼠标并拖动时绘制选择框,然后在释放鼠标后消失。 Unfortunately I've run into a problem. 不幸的是,我遇到了一个问题。

jsFiddle example: http://jsfiddle.net/7F9fy/ jsFiddle示例: http : //jsfiddle.net/7F9fy/

The main problem is somewhere in onmousemove (or related to it): 主要问题在于onmousemove中的某个地方(或与其相关的地方):

whiteRect.connect("onmousemove",function(e) {
    if(isMouseDown) {
        if(whiteRect.groupSelector_) {
            pStat.innerHTML = "dragging...";
            console.debug("dragging...");
            e.stopImmediatePropagation();
            e.preventDefault();
            var ex = (e.x ? e.x : e.clientX);
            var ey = (e.y ? e.y : e.clientY);                   

            if(groupSelector) {
                // Also tried getShape, editing that shape, and setShape on groupSelector--same
                // behavior, though.                    
                var rectX = (ex - cnvDiv.offsetLeft < whiteRect.groupSelector_.x ? ex - cnvDiv.offsetLeft : whiteRect.groupSelector_.x);
                var rectY = (ey - cnvDiv.offsetTop < whiteRect.groupSelector_.y ? ey - cnvDiv.offsetTop : whiteRect.groupSelector_.y);

                surface.remove(groupSelector);
                groupSelector = surface.createRect({
                    x: rectX,
                    y: rectY, 
                    width: Math.abs(ex - cnvDiv.offsetLeft - whiteRect.groupSelector_.x), 
                    height: Math.abs(ey - cnvDiv.offsetTop - whiteRect.groupSelector_.y)
                }).setStroke({color: "blue", width: 3});

            } else {
                groupSelector = surface.createRect({
                    x: whiteRect.groupSelector_.x,
                    y: whiteRect.groupSelector_.y,
                    width: Math.abs(ex - cnvDiv.offsetLeft - whiteRect.groupSelector_.x), 
                    height: Math.abs(ey - cnvDiv.offsetTop - whiteRect.groupSelector_.y)
                }).setStroke({color: "blue", width: 3});
            }
            e.stopPropagation();
        }
    }
});

If I hold down the left mouse button in the shape/group (the white square in the above example) to which my mouse events are connected and start dragging, the box begins to draw, following my drag motion. 如果我在鼠标事件所连接的形状/组(在上面的示例中为白色正方形)上按住鼠标左键并开始拖动,则在拖动动作之后,该框开始绘制。 When I release the mouse, sometimes the box disappears, and sometimes, it doesn't. 当我释放鼠标时,有时该框消失,有时却不消失。 When it doesn't, the box keeps being drawn and follows mouse movements as defined to do when I'm dragging. 如果没有,则该框将继续绘制,并按照定义的鼠标移动进行拖动。

In the jsFiddle, if you watch console.debug or the paragraph reporter under the canvas, you'll see that on occasion, onmouseup doesn't fire when you release the mouse (I checked for mouseup as well, but that has the same issue). 在jsFiddle中,如果您观看console.debug或画布下的段落报告器,您会发现有时释放鼠标时onmouseup不会触发(我也检查过mouseup,但是存在相同的问题)。 In cases where onmouseup never fires, onmousemove continues to fire. 在onmouseup永不触发的情况下,onmousemove继续触发。 If you click again, sometimes a full mouse click series fires (down, up, click, and move), which then makes the drawn rectangle disappear. 如果再次单击,有时会触发完整的鼠标单击系列(向下,向上,单击和移动),然后使绘制的矩形消失。 Sometimes this doesn't happen, though, and onmousemove keeps firing. 有时候,这不会发生,并且onmousemove会继续触发。 If you click after the drag/onmousemove becomes 'stuck' and nothing happens, there are no debug lines or changes to reporters for those events, so it's as if all mouse events except onmousemove are being squelched. 如果在拖动/ onmousemove被“卡住”后单击,并且什么都没有发生,则这些事件没有调试行或对报告程序的更改,因此,好像所有鼠标事件(除了onmousemove一样)都被抑制。 I tried adding in stopPropagation, stopImmediatePropagation, and preventDefault, but that didn't help. 我尝试添加stopPropagation,stopImmediatePropagation和preventDefault,但这没有帮助。 I also tried using Dojo event's stop, but that didn't change the behavior. 我也尝试使用Dojo事件的stop,但是并没有改变行为。

For re-drawing the box in onmousemove, I've tried both 'getShape -> edit properties -> setShape' as well as deleting the shape and making a whole new one; 为了在onmousemove中重新绘制该框,我尝试了“ getShape->编辑属性-> setShape”以及删除形状并制作一个新形状。 neither of these methods stopped the problem and there wasn't any appreciable difference between them. 这些方法都不能解决问题,并且它们之间没有任何明显的区别。

I'm using Dojo 1.8.3, and this happens in both Chrome (v25) and Firefox (v19), with either Canvas or SVG as the renderer. 我使用的是Dojo 1.8.3,这种情况发生在Chrome(v25)和Firefox(v19)中,使用Canvas或SVG作为渲染器。

Thoughts? 有什么想法吗? Am I missing something obvious here? 我在这里错过明显的东西吗?

Sorted it out. 整理出来。 The problem is the onmouseup event when you decide to stop dragging out the shape can fire on the underlying/attached shape, or on the shape you're dragging. 问题是onmouseup事件,当您决定停止拖出形状时,可能会在基础/附加形状或要拖动的形状上触发。 It's random, depending on the cursor position, but favors the drawn shape if you don't have an offset or delay in your drag. 它是随机的,具体取决于光标的位置,但是如果拖动没有偏移或延迟,则偏向于绘制形状。 (Moveable.js and Mover.js in dojox/gfx pointed me in the right direction.) (dojox / gfx中的Moveable.js和Mover.js为我指明了正确的方向。)

I changed my box to a path in the course of trying to make it work, and this seems to perform better, but isn't necessary. 在尝试使其工作的过程中,我将盒子更改为一条路径,这看起来效果更好,但这不是必需的。

The key was to make a general 'onMouseUp' function, then call that from both the originator-shape's onmouseup as well as the dragged shape's onmouseup. 关键是要创建一个通用的“ onMouseUp”函数,然后从原始形状的onmouseup以及拖动的形状的onmouseup中调用它。 My example is sloppy, but I hope it gets the point across. 我的例子很草率,但我希望它能说明问题。

jsFiddle: http://jsfiddle.net/n3KGY/1/ jsFiddle: http : //jsfiddle.net/n3KGY/1/

Key code: 关键代码:

// General method to clear out a selector if
// one was being drawn.
var selectorMouseUp = function(e) {
    reporter.innerHTML = "onmouseup";
    isMouseDown = false;
    whiteRect.groupSelector_ = null;
    if(groupSelector) {
        if(selectorUp) {
            groupSelector.disconnect(selectorUp);
        }               
        surface.remove(groupSelector);
        groupSelector = null;
    }
    e.stopImmediatePropagation();
    e.stopPropagation();
    e.preventDefault();
};

// Mouseup event for the background/workspace
whiteRect.connect("onmouseup",function(e){
    selectorMouseUp(e);
});

// Make a selector as a path on the surface
// and attach a mouseup to it
var makeSelector = function(x,y,w,h) {
    groupSelector = surface.createPath()
        .moveTo(x,y)
        .hLineTo(x+w).vLineTo(y+h).hLineTo(x).vLineTo(y)
        .setStroke({color: "blue", width: 3})
        .closePath();
    // Attach the same mouseup method as the workspace/background
    selectorUp = groupSelector.connect("onmouseup",function(e){
        reporter.innerHTML = "onmouseup (selector)";
        selectorMouseUp(e);
    });         
};

bigRect.connect("onmousemove",function(e){  
    if(isMouseDown) {
        if(bigRect.groupSelector_) {
            var ex = e.clientX;
            var ey = e.clientY;

            reporter.innerHTML = "dragging at " + ex+","+ey;

            var downX = bigRect.groupSelector_.x;
            var downY = bigRect.groupSelector_.y;
            var leadingX = (ex - grn.offsetLeft < downX ? ex - grn.offsetLeft : downX);
            var leadingY = (ey - grn.offsetTop < downY ? ey - grn.offsetTop : downY);
            var selWidth = Math.abs(ex - grn.offsetLeft - downX);
            var selHeight = Math.abs(ey - grn.offsetTop - downY);

            if(groupSelector) {
                // If there's already a selector being drawn, get rid of it.
                groupSelector.disconnect(selectorUp);
                surface.remove(groupSelector);
            }
            // Draw the current selector
            makeSelector(leadingX,leadingY,selWidth,selHeight);
            e.stopImmediatePropagation();
            e.stopPropagation();
            e.preventDefault();
        }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM