【问题标题】:RaphaelJS shapes Drag&Drop demoRaphael JS 形状拖放演示
【发布时间】:2012-04-02 16:48:41
【问题描述】:

我试图理解这个演示的工作: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];
        }
    }
}

谁能向我解释它的作用和工作原理?谢谢。

【问题讨论】:

    标签: javascript raphael


    【解决方案1】:

    在这个 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}],
    

    因此,您有 2 个对象 obj1 和 obj2 想要通过路径连接在一起。路径必须绘制到对象边缘的 4 个可能点中的任何一个:

    我根据它们在 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

    • 我们没有 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

    那么

    • 这个连接是有效的,对点的距离做一个廉价的测量(dy + dx)并将这些有效的连接放在一个数组中。我们稍后会选择“最短”​​的距离。

    如果被测试的点不是这些相反对之一,那么我们仍然会测量它。如果我们能提供帮助,这一切都是为了阻止路径进入 2 个对象内部。查看它们是否在同一侧的第一个测试是跳过所有这些相反测试代码的廉价方法。在我们测量了所有允许的点之后,我们选择最小的 dy+dx 并使用这些点来绘制路径。

    【讨论】:

      猜你喜欢
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      相关资源
      最近更新 更多