RaphaelJS塑造拖放演示

Guy*_*kes 4 javascript raphael

我试着理解这个演示的工作: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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释它的作用和工作原理吗?谢谢.

Mat*_*sch 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}],
Run Code Online (Sandbox Code Playgroud)

所以你有2个对象obj1和obj2,你想要与路径连接在一起.必须将路径绘制到对象边缘上的4个可能点中的任何一个点:

路径位置

我在哪里根据p中的索引标记了顶点.现在我们将循环遍历obj1上的点和obj2上的点,使用i作为obj1上的点的索引,使用j作为obj2上的点的索引.这样我们就obj2上的每个点测试obj1上的每个点.我们的目标是测量(排序)我们认为适合连接的那些点之间的距离.

// 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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以打破那个大的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)做一个便宜的测量并将这些有效的连接放在一个数组中.我们稍后会选择"最短"​​距离.

只有连接

如果被测试的点不是这些相对的对中的一个,那么我们仍然测量它.如果我们可以帮助它,这就是阻止路径进入2个对象的全部内容.第一个测试它们是否在同一侧的测试是一种廉价的方法来跳过所有这些相反的测试代码.在我们测量了所有允许的点之后,我们选择最小的dy + dx并使用这些点来绘制路径.