Question

i am trying to add more connecting points to shapes in graffle example, so far i have computed the connecting points available to the rectangle shape as my app will have only rectangles for now and added them to the array p.

the main thing i can't understand is how to modify the connection main loop to use the connecting points which are closer and are not already used.

the objects are moveable so i guess i would have to change the loop to get the direction of the objects and the closest free connecting nodes available, can some one help me out or guide me how to achieve this?

this is the original graffle code for reference

 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}],
    d = {}, dis = [];
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];
        }
    }
}
if (dis.length == 0) {
    var res = [0, 4];
} else {
    res = d[Math.min.apply(Math, dis)];
}
var x1 = p[res[0]].x,
    y1 = p[res[0]].y,
    x4 = p[res[1]].x,
    y4 = p[res[1]].y;
dx = Math.max(Math.abs(x1 - x4) / 2, 10);
dy = Math.max(Math.abs(y1 - y4) / 2, 10);
var x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3),
    y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3),
    x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3),
    y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3);
var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(",");
Was it helpful?

Solution 2

after hours of messing with my code and thanks to Hakan SONMEZ, i came to a solution to my own question that is:

  1. first initialize the available nodes of the shape (in my case rectangle) when it is created
  2. store the nodes in rapahel object data
  3. when connection is created use the available nodes of both shapes and find closest one then draw the line
  4. remove those nodes from both shapes or store them as used nodes
  5. on moving object reset all nodes of both shapes and then render connections again

view how things look like and the working example: View Example

the code is not yet perfect but will provide base for others to modify it according to their usage, please share if any suggestions or modifications.

OTHER TIPS

I make own connections. http://jsfiddle.net/XcsN/fKpGD/

If you get your shapes' coordinates yo will calculate connections points. You can get your shape' coordinates like this: In this example your connections connect the shapes x,y (starting position)

    function start(){
        //TODO         
    },
    function move(){
        //TODO
         move_arrows();
    },
    function up(){};

    rectangleStart.drag(move, start, up);
    rectangleEnd.drag(move, start, up);
    function move_arrows(){
       boxStart = rectangleStart.getBBox();
       boxEnd = rectangleEnd.getBBox();
       connection.remove();
       connection = new Connection(boxStart.X,boxStart.Y,boxEnd.X,boxEnd.Y);
    }

    function Connection(BX, BY, SX, SY) {
         return paper.path("M" + BX + " " + BY + " L" + SX + " " + SY);
    }

sorry for my Turkish declarations in jsfiddle. If you want just like connections in example, you should upgrade your Connection function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top