0

我有一条从一点到另一点的线。我在允许移动线的线的末端添加圆圈。

但是,当我移动圆圈并且线更新时,另一条线正在以某种方式更新自己的点。

之前(运动应该只发生在屏幕的右侧): 前

后: 后

这是小提琴:http: //jsfiddle.net/Robodude/s86xc/1/

(由于某种原因,在 js fiddle 上的 chrome 中无法可靠地绘制线条......它在本地工作正常,但在网上我只能让它们在 FF 上显示)

基本说明: 在左侧网格中,单击一个圆圈。单击第二个圆圈。应在点之间画一条线。单击“将 Q 复制到 A”按钮,应在右侧框架中绘制线条,并带有可以拖动的圆形端点。

在右侧,这是怎么回事:

1)在右侧组中绘制线条。

2)在线条的末端绘制圆圈。

3) 给圆引用所有在其中心开始/结束的线

4) 拖动时,圆圈会更新其引用的线条。

据我所知,这些圆圈没有参考左侧面板中的线条。

左侧线的名称为“line”,右侧的线(圆圈有参考)的名称为“line2”

这就是我给圆圈引用线条的方式。如果 x,y 坐标处的圆圈已经存在,则将线推送到它的 connectedLines 属性

var circleTest = circleGroup.get("." + point.x + ", " + point.y)[0];
if (circleTest == null) {
    var circle = new Kinetic.Circle({
        name: (point.x) + ", " + (point.y),
        x: point.x,
        y: point.y,
        radius: answer ? 15 : 10,
        stroke: "rgba(0,0,0,1)",
        strokeWidth: "3",
        fill: "rgba(255, 255, 255, 1)",
        connectedLines: [line],
        draggable: answer ? false: true,
        oldX: point.x,
        oldY: point.y,
        dragBoundFunc: answer ? null : function (pos) {
            var x = pos.x;
            var y = pos.y;

            var newPos = { x: x - offset.x, y: y - offset.y };

            updateAttachedLines(newPos, this);

            return {
                x: x,
                y: y
            }
        }
    });

    circle.on("click", function () {
        console.log(this.attrs.connectedLines);
    });

    circleGroup.add(circle);
}
else {
    circleTest.attrs.connectedLines.push(line);
}

这是 updateAttachedLines 的样子:

function updateAttachedLines(pos, circle)
{
    var x = pos.x;
    var y = pos.y;
    var ox = circle.attrs.oldX;
    var oy = circle.attrs.oldY;

    var cls = circle.attrs.connectedLines;

    for (var i = 0; i < cls.length; i++) {
        var cl = cls[i];
        console.log(cl.attrs.name);
        var points = cl.getPoints();

        var newPoints = [];
        for (var n = 0; n < points.length; n++) {
            var point = points[n];

            if ((point.x == ox) && (point.y == oy)) {
                point.x = x;
                point.y = y;
            }

            newPoints.push(point);
        }

        cl.setPoints(newPoints);
    }

    circle.parent.parent.draw();

    circle.attrs.oldX = x;
    circle.attrs.oldY = y;
}

那么为什么右手边线的移动会影响左手边线呢?

4

1 回答 1

2

即使您在for时创建了一个新Kinetic.Line对象,您也不会复制原始线的点,而是传递参考。buildLinesanswerGroup

这意味着,在更改 中的线的点时answerGroup,您最终也会更改 中的原始线的点lineGroup

现在,按照这种直觉,一般的想法是在line.points.slice()创建新Kinetic.Line的 in时复制点的数组buildLines。如果总是一个数字数组,这实际上会起作用line.points,但它可以是三种类型:

points: [Number, Number, Number, ...]
or
points: [Array, Array, Array, ...]
or
points: [Object, Object, Object, ...]

因此,现在应该确保在为答案组创建新行时,它从原始行获得的点都是副本,而不是参考。实现此目的的一种方法是使用mapon line.points

让回调为:

var _copyPts = function(e, i, a) {
    if(e instanceof Array) {
        return e.slice();
    }
    else if(e instanceof Object) {
        var r = {};
        for(var k in e) {
            if(e.hasOwnProperty(k)) r[k] = e[k];
        }
        return r;
    }

    return e;
};

而且,变化buildLines是:

...
var lineShape = new Kinetic.Line({
    id: "l" + i,
    name: "line2",
    stroke: answer ? "rgba(000,000,000,1)" : line.color,
    strokeWidth: answer ? 8 : 5,
    points: line.points.map(_copyPts),     //<--- change here
    dashArray: answer ? [10, 5] : null
});
...

这是一个工作版本

于 2013-05-24T05:09:39.093 回答