【问题标题】:snap svg gluing line endpoints for drag and dropsnap svg 粘合线端点以进行拖放
【发布时间】:2016-10-27 11:40:33
【问题描述】:

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

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

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

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

需要建议。谢谢。

【问题讨论】:

    标签: svg drag-and-drop snap.svg rubber-band


    【解决方案1】:

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

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

    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的链接

    【讨论】:

      猜你喜欢
      • 2014-05-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      相关资源
      最近更新 更多