Frage

I'm making an interactive diagram website and I'm trying to easily draw arrows in kineticJS relative to the stagesize, i've got the following: http://jsfiddle.net/K5Zhg/17/

But as you can see the rotated arrow is not matching the intended start and ending point. I tried offset, but that messes up the correct (not rotated) arrow. Also don't know why jsfiddle show's my arrows this messy (missing bottom line), on my own machine it seems to be working fine (using v5.1.0), see also here http://tomzooi.com/dump/ip/ (using kineticjs and binding bootstrap to it, working nice so far)

code:

var stage = new Kinetic.Stage({
    container: 'container',
    width: 1140,
    height: 500
});

var layer = new Kinetic.Layer();


var border = new Kinetic.Rect( {
    x: 0,
    y: 0,
    width: stage.getWidth(),
    height: stage.getHeight(),
    stroke: ' red',
    strokeWidth: 1
});
layer.add(border);

var dot = new Kinetic.Circle({
    x: 0.1*stage.getWidth(),
    y: 0.1*stage.getHeight(),
    radius: 10,
    fill: 'red'
});
var dot2 = new Kinetic.Circle({
    x: 0.5*stage.getWidth(),
    y: 0.1*stage.getHeight(),
    radius: 10,
    fill: 'red'
});
var dot3 = new Kinetic.Circle({
    x: 0.5*stage.getWidth(),
    y: 0.5*stage.getHeight(),
    radius: 10,
    fill: 'red'
});
layer.add(dot);
layer.add(dot2);
layer.add(dot3);

var arrow1 = arrow(0.1,0.1,0.5,0.1,10);
var arrow2 = arrow(0.1,0.2,0.5,0.5,10);
layer.add(arrow1);
layer.add(arrow2);
// add the layer to the stage
stage.add(layer);

function arrow(psx, psy, pex, pey, pw) {
    var w = stage.getWidth();
    var h = stage.getHeight();

    var sx = psx*w;
    var ex = pex*w;
    var sy = psy*h;
    var ey = pey*h;

    var pr = (Math.atan2(ey-sy, ex-sx)/(Math.PI/180));
    var pl = Math.sqrt(Math.pow((ex-sx),2)+Math.pow((ey-sy),2));

    ex = sx+pl;
    ey = sy;

    var poly = new Kinetic.Line({
        points: [sx,sy+pw,  sx,sy-pw,   ex-3*pw,ey-pw,      ex-3*pw,ey-2*pw,      ex,ey,      ex-3*pw,ey+2*pw,   ex-3*pw, sy+pw],
        fill: '#EDECEB',
        stroke: '#AFACA9',
        strokeWidth: 2,
        closed: true,
        rotation: pr,
        shadowColor: 'black',
        shadowBlur: 10,
        shadowOffset: {x:2,y:2},
        shadowOpacity: 0.5
      });
    return poly;
}
War es hilfreich?

Lösung

Here is a solution: http://jsfiddle.net/K5Zhg/20/

The problem was that when you rotate the arrow shape, it rotates around x=0 and y=0. However your point was drawn on x=sx and y=sy (in your example case x=60 and y=50).

To fix this draw the points around x=0 and y=0 (and translating the other points in the array using the correct variables) and then setting the x and y property of the Kinetic.Line to sx and sy in order set the position back to its intended location. I.e.

function arrow(psx, psy, pex, pey, pw) {
        var w = stage.getWidth();
        var h = stage.getHeight();

        var sx = psx*w;
        var ex = pex*w;
        var sy = psy*h;
        var ey = pey*h;

        // console.log(sx);

        var pr = (Math.atan2(ey-sy, ex-sx)/(Math.PI/180));
        var pl = Math.sqrt(Math.pow((ex-sx),2)+Math.pow((ey-sy),2));
        ex = sx+pl;
        ey = sy;

        var poly = new Kinetic.Line({
            points: [0,0+pw,    
                0,0-pw, ex-sx-3*pw,ey-sy-pw,        ex-sx-3*pw,ey-sy-2*pw,    ex-sx,ey-sy,    ex-sx-3*pw,ey-sy+2*pw,   ex-sx-3*pw, 0+pw],
            fill: 'blue',
            stroke: 'black',
            strokeWidth: 2,
            closed: true,
            rotation: pr,
            x: sx,
            y: sy,
            shadowColor: 'black',
            shadowBlur: 10,
            shadowOffset: {x:2,y:2},
            shadowOpacity: 0.5
          });

        return poly;
    }

I also changed the y value to 0.1 instead of the 0.2 such that the start of the second arrow connects with the red dot.

Oh and I updated the Fiddle to uses v5.0.1.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top