【问题标题】:Dart SVG Drag and Drop Slipping MouseDart SVG 拖放滑动鼠标
【发布时间】:2013-12-08 09:14:38
【问题描述】:

我尝试使用 SVG 在 Dart 中创建拖放行为。我有BasicUnits,基本上是GElement (<g>)s。现在它有一个body,即RectElement。我正在使用该元素来移动设备。这是定义:

class BasicUnit {

  SvgSvgElement canvas;
  GElement group;
  RectElement body;
  bool dragging;
  num dragOffsetX, dragOffsetY, width, height;

  BasicUnit(SvgSvgElement this.canvas, num x, num y, num this.width, num this.height) {
    this.body = new RectElement();
    this.body.setAttribute('x', '$x');
    this.body.setAttribute('y', '$y');
    this.body.setAttribute('width', '$width');
    this.body.setAttribute('height', '$height');
    this.body.classes.add('processing_body');

    this.body.onMouseDown.listen(select);
    this.body.onMouseMove.listen(moveStarted);
    this.body.onMouseUp.listen(moveCompleted);
    this.body.onMouseLeave.listen(moveCompleted);

    this.group = new GElement();
    this.group.append(this.body);

    this.dragging = false;
  }

  void select(MouseEvent e) {
    e.preventDefault();
    this.dragging = true;

    var mouseCoordinates = getMouseCoordinates(e);
    this.dragOffsetX = mouseCoordinates['x'] - body.getCtm().e; //double.parse(body.attributes['x']);
    this.dragOffsetY = mouseCoordinates['y'] - body.getCtm().f;
  }

  void moveStarted(MouseEvent e) {
    e.preventDefault();

    if (dragging) {
      var mouseCoordinates = getMouseCoordinates(e);
      num newX = mouseCoordinates['x'] - dragOffsetX;
      num newY = mouseCoordinates['y'] - dragOffsetY;
      this.body.setAttribute('transform', 'translate($newX, $newY)');
    }
  }

  void moveCompleted(MouseEvent e) {
    e.preventDefault();
    this.dragging = false;
  }

  dynamic getMouseCoordinates(e) {
    return {'x': (e.offset.x - this.canvas.currentTranslate.x)/this.canvas.currentScale, 
            'y': (e.offset.y - this.canvas.currentTranslate.y)/this.canvas.currentScale};
  }
}

我有一个Application 对象。它获取给定idsvg 元素。这是定义:

class Application {
  int WIDTH = 80, HEIGHT = 60;
  SvgSvgElement canvas;

  Application(canvas_id) {
    this.canvas = document.querySelector(canvas_id);
    this.canvas.onDoubleClick.listen((MouseEvent e) => addUnit(e));
  }

  void addUnit(MouseEvent e) {
    num x = e.offset.x - WIDTH/2;
    num y = e.offset.y - HEIGHT/2;
    BasicUnit newUnit = new BasicUnit(this.canvas, x, y, WIDTH, HEIGHT);
    this.canvas.append(newUnit.group);
  }
}

我的问题是我的鼠标滑过BasicUnit<g> 元素。当您选择靠近其边缘的元素并尝试拖动时,突然元素被丢弃。如果您尝试快速拖放,情况也是如此。我尝试按照this webpage 上的示例进行操作,但无法弄清楚问题所在。

更新 完整的源代码可用here

更新二 Here 是一个演示。

【问题讨论】:

    标签: html svg dart


    【解决方案1】:

    在您双击页面后,浏览器正在尝试拖动选定的文本。这可以通过阻止 onMouseDown 事件的默认行为(您的选择方法)轻松解决:

    void select(MouseEvent e) {
      e.preventDefault();
      this.dragging = true;
      this.group.parentNode.append(this.group);
    
      var mouseCoordinates = this.getMouseCoordinates(e);
      this.dragOffsetX = mouseCoordinates['x'] - this.body.getCtm().e;        
      this.dragOffsetY = mouseCoordinates['y'] - this.body.getCtm().f; 
    }
    

    另一个问题是由于 svg 绘制速度不够快而无法跟上鼠标坐标。因此,当移动得足够快时,鼠标坐标会移动到 SVG 元素的主体之外,因此该元素将不再获得鼠标移动事件。这可以通过侦听背景 SVG 元素(在您的示例中为画布)上的 onMouseMove 和 onMouseLeave 事件而不是被移动的元素来解决:

    body.onMouseDown.listen(select);
    canvas.onMouseMove.listen(moveStarted);
    body.onMouseUp.listen(moveCompleted);
    canvas.onMouseLeave.listen(moveCompleted);
    

    编辑:

    使用上述方法有效,除非当被拖动的元素位于另一个元素下方时发生 onMouseUp,在这种情况下,该元素仍被拖动,直到该元素上发生另一个 onMouseUp 事件,或者光标移出查看区域。这可以通过在画布上监听 onMouseUp 事件而不是 body 来解决:

    canvas.onMouseUp.listen(moveCompleted);
    

    this example

    此外,最好在单击元素时打开 onMouseMove、onMouseUp 和 onMouseLeave 侦听器(在您的 select 方法中),然后禁用 onMouseUp 和 onMouseLeave 上的侦听器(moveCompleted 方法)。我在上面的例子中已经这样做了。

    【讨论】:

    • 感谢您的努力,但滑倒问题仍然存在。事实上,收听canvasonMouseMoveonMouseLeave 最终会卡在一个单元上,除非您将鼠标光标移出canvas。请参考问题中的示例链接,该链接工作正常。
    • 对我来说工作正常,我没有遇到您遇到的问题。试试this example,如果您仍然遇到同样的问题,请告诉我。
    • 我想我找到了您所指的问题。我会更新我的答案以反映我的发现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多