计算偏移箭头尖端与箭头线FabricJS

时间:2014-04-17 11:54:19

标签: canvas html5-canvas fabricjs

我正在尝试创建一个允许您在画布上直播箭头的功能。到目前为止,我的工作正在进行中,但我仍坚持计算,在移动时将箭头尖端固定到线的末端。我附上了一张图片,表明角度计算正确。

enter image description here

我只需要移动小费,但我无法理解。非常感谢!!

PS:提示是一条路径,但也许有更好的解决方案?

function drawArrowMouseDown( e ) {
    var mouse = canvas.getPointer(e.e);
    started = true;
    lastX = mouse.x;
    lastY = mouse.y;

    var $color = colors[self.selectedColor] != undefined ? colors[self.selectedColor] : 'red';

    var line = new fabric.Line( [lastX,lastY,lastX,lastY], {
        stroke: $color,
        strokeWidth:  3,
        lockScalingX: true,
        lockScalingY: true,
        lockRotation: true,
        hasBorders:   false,
        hasControls:  false,
        perPixelTargetFind: true,
        fill:         $color,
        strokeLineCap: 'round'
    });
    line.lockScalingX = line.lockScalingY = true;

    var tip = new fabric.Path('M 0 0 L -20 15 M 0 0 L 20 15 z', {
        left: lastX,
        top: lastY,
        strokeWidth: 3,
        stroke: 'blue',
        strokeLineCap: 'round',
        hasControls: false,
        originX: 'center',
        originY: 'center'
    });

    tip.line = line;
    line.tip = tip;

    canvas.add(line);
    canvas.add(tip);

    tip.bringToFront();

    canvas.setActiveObject(line);
    canvas.renderAll();
}
function drawArrowMouseMove( e ) {
    if(!started) {
        return false;
    }
    var mouse = canvas.getPointer(e.e);

    var line = canvas.getActiveObject();
    line.set('x2', mouse.x).set('y2', mouse.y);
    line.setCoords();

    var tip = line.get('tip');
    tip.set({ x1: mouse.x, y1: mouse.y, x2: lastX, y2: lastY });

    var x = tip.get('x2') - tip.get('x1');
    var y = tip.get('y2') - tip.get('y1');

    var angle;
    if (x == 0) {
        if (y == 0) {
            angle = 0;
        }
        else if (y > 0) {
            angle = Math.PI / 2;
        }
        else {
            angle = Math.PI * 3 / 2;
        }
    }
    else if (y == 0) {
        if (x > 0) {
            angle = 0;
        }
        else {
            angle = Math.PI;
        }
    }
    else {
        if (x < 0) {
            angle = Math.atan(y / x) + Math.PI;
        }
        else if ( y < 0) {
            angle = Math.atan(y / x) + (2 * Math.PI);
        }
        else {
            angle = Math.atan(y / x);
        }
    }
    angle = angle * 180 / Math.PI;

    tip.set('angle', angle-90);

    canvas.renderAll();
}

1 个答案:

答案 0 :(得分:0)

你的角度计算有点偏。

而是使用atan2,结果标准化为PI * 2:

var dx = tip.get('x2') - tip.get('x1');

var dy = tip.get('x2') - tip.get('x1');

var PI2=Math.PI*2;

var radianAngle = ( Math.atan2(dy,dx)+PI2 ) % PI2;