RaphaelJS形状拖放演示

4

我试着理解这个演示的作用:http://raphaeljs.com/graffle.html 但是我无法理解graffle.js源代码中的循环:

for (var i = 0; i < 4; i++) {
    for (var j = 4; j < 8; j++) {
        var dx = Math.abs(p[i].x - p[j].x),
            dy = Math.abs(p[i].y - p[j].y);
        if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) {
            dis.push(dx + dy);
            d[dis[dis.length - 1]] = [i, j];
        }
    }
}

有人能解释一下这是做什么的以及它如何工作吗?谢谢。

1个回答

12

在这个for循环之前,会构建一个包含每个对象路径可以连接的4个位置的单个数组。

var bb1 = obj1.getBBox(),
    bb2 = obj2.getBBox(),
    p = [{x: bb1.x + bb1.width / 2, y: bb1.y - 1},
    {x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1},
    {x: bb1.x - 1, y: bb1.y + bb1.height / 2},
    {x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2},
    {x: bb2.x + bb2.width / 2, y: bb2.y - 1},
    {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1},
    {x: bb2.x - 1, y: bb2.y + bb2.height / 2},
    {x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2}],

假设你有两个对象 obj1 和 obj2,你想用路径将它们连接在一起。路径必须绘制到对象边缘的四个可能点之一:

path positions

我已经根据它们在p中的索引标记了顶点。现在我们将循环遍历obj1上的点和obj2上的点,使用i表示obj1上的点的索引,使用j表示obj2上的点的索引。这样,我们测试每个obj1上的点与每个obj2上的点。我们的目标是仅测量适合连接的那些点之间的距离(有点像)。

// For each pair of adjacent points
for (var i = 0; i < 4; i++) {
    for (var j = 4; j < 8; j++) {

        // Calculate the difference in the X and Y direction (dy and dx)
        var dx = Math.abs(p[i].x - p[j].x),
            dy = Math.abs(p[i].y - p[j].y);

             // If the points are on the same side  OR  
        if ((i == j - 4) || 
            // If the points are **not** opposites (3 and 6) or (2 and 7) or (0 and 5) or (1 and 4) 
            // or, if we have 3 and 6, and the obj1 is to the left side of obj2
            // or, if we have 2 and 7, and the obj1 is to the right side of obj2
            // or, if we have 0 and 5, and the obj1 is higher than obj2
            // or, if we have 1 and 4, and the obj1 is lower than obj2

            (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) {
            // push the sum of dx and dy onto out distance list
            // and push the associated pair of points onto the d list.
            // This is so we can pick the sort-of-closest pair of points.
            dis.push(dx + dy);
            d[dis[dis.length - 1]] = [i, j];
        }
    }
}

那么,为了分解这个大的if语句:

如果

  • 我们有两个在同一侧的点

    (i == j - 4)

或者

  • 我们没有3和6,或者如果有,点3在点6的左边

    ((i != 3 && j != 6) || p[i].x < p[j].x) &&

  • 我们没有2和7,或者如果有,点2在点6的右边

    ((i != 2 && j != 7) || p[i].x > p[j].x) &&

  • 我们没有0和5,或者如果有,点0在点5的上面

    ((i != 0 && j != 5) || p[i].y > p[j].y) &&

  • 我们没有1和4,或者如果有,点1在点4下面

    ((i != 1 && j != 4) || p[i].y < p[j].y)

那么

  • 这条连接是有效的,在测量这些有效连接的距离(dy+dx)后将它们放入一个数组中。稍后我们将选择“最短”的距离。

only if connections

如果被测试的点不是这些相对的一对,则我们仍然进行测量。这是为了防止路径在两个对象内部,如果可能的话。第一个测试以查看它们是否在同一侧是跳过所有这些相反测试代码的一种廉价方式。在我们测量了所有允许的点之后,我们选择最小的dy+dx并使用这些点绘制路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接