gpt4 book ai didi

html - Dart SVG 拖放滑动鼠标

转载 作者:行者123 更新时间:2023-11-28 01:50:23 25 4
gpt4 key购买 nike

我尝试使用 SVG 在 Dart 中创建拖放行为。我有BasicUnit基本上是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目的。它得到 svg给定的元素 id .这是定义:

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是一个演示。

最佳答案

在您双击页面后,浏览器试图拖动所选文本。这可以通过阻止 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 元素(在您的示例中为 Canvas )而不是正在移动的元素上的 onMouseMove 和 onMouseLeave 事件来解决:

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

编辑:

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

canvas.onMouseUp.listen(moveCompleted);

参见 this example .

此外,当元素被单击时(在您的 select 方法中)打开 onMouseMove、onMouseUp 和 onMouseLeave 监听器可能会更好,然后禁用 onMouseUp 和 onMouseLeave 上的监听器(moveCompleted 方法)。我在上面的示例中已经这样做了。

关于html - Dart SVG 拖放滑动鼠标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20451699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com