3

我有两个可以拖动的视觉对象。我想在它们之间“粘合”一条线,以便当我拖动一个对象时,该线会调整并保持在拖动对象上的相同相对点(想想 node-red、jointjs、cad/cam)。

视觉对象是使用元素组(在 0,0 处)创建的。拖动是通过平移组对象的矩阵来实现的。(我想使用矩阵,因为这将有助于将来放大和缩小)。

我想创建一种新的“线”,它包含两个元素——起点和终点。起点与可视对象 1 分组,端点与对象 2 分组。如果拖动对象 2,则线的端点将包含在组 2 的矩阵变换中,并与该对象保持一致。(与对象 1 和起点类似)。

我是 snap 和 js 的新手。我被困在如何创建这样一个包含起点和终点元素的新“线”元素(例如,如何扩展线原型或“子类”它)。

需要建议。谢谢。

4

1 回答 1

3

我想这就是你要找的。它在屏幕上的两个正方形之间附加一条线,您可以拖动它。

为可拖动的矩形创建一个 snap 插件。

Snap.plugin(function (Snap, Element, Paper, global, Fragment) {

获取当前转换。

    function dragStart(x, y, e) {
        this.current_transform = this.transform();
    }

更新当前转换。

    function dragMove(dx, dy, x, y, e) {
        this.transform(this.current_transform+'T'+dx+','+dy);
        this.updatePaths();
    }

保存当前转换。

    function dragEnd(e) {
        this.current_transform = this.transform();
    }

遍历每个保存的路径并更新其路径属性。调用 prependTo - 以确保它位于矩形后面。

    function updatePaths() {
        var key;
        for(key in this.paths) {
            this.paths[key][0].attr({"path" : this.getPathString(this.paths[key][1])});
            this.paths[key][0].prependTo(paper);
        }
    }

获取每个元素的坐标。

    function getCoordinates() {
        return [this.matrix.e + (this.node.width.baseVal.value / 2),
          this.matrix.f + (this.node.height.baseVal.value / 2)];
    }

使用两个元素坐标获取路径字符串。

    function getPathString(obj) {
        var p1 = this.getCoordinates();
        var p2 = obj.getCoordinates();
        return "M"+p1[0]+","+p1[1]+"L"+p2[0]+","+p2[1];
    }

添加两个元素的路径。使用他们的 ID 作为参考。Snap 会自动为元素创建一个随机 ID,因此我们不需要这样做。

    function addPath(obj) {
        var path = paper.path(this.getPathString(obj))
            .attr({
              fill:'none', 
              stroke:'blue',
              strokeWidth:1
            });

        path.prependTo(paper);
        this.paths[obj.id] = [path, obj];
        obj.paths[this.id] = [path, this];            
    }

创建您的 draggableRectangle 原型并附加所有功能。

    Paper.prototype.draggableRect = function (x, y, w, h) {

        var rect = paper.rect(0,0,w,h).attr({id: id}).transform("T"+x+","+y);
        rect.paths = {};
        rect.drag(dragMove, dragStart, dragEnd);
        rect.updatePaths = updatePaths;
        rect.getCoordinates = getCoordinates;
        rect.getPathString = getPathString;
        rect.addPath = addPath;

        return rect;
    };
});

创建纸张。

var paper = Snap("#svgout");

创建可拖动的矩形。

var rect1 = paper.draggableRect(0, 0, 40, 40);
var rect2 = paper.draggableRect(0, 0, 40, 40);

将它们相互连接。

rect1.addPath(rect2);

这是JSFiddle的链接

于 2016-06-30T14:14:52.847 回答