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

Canvas 计算偏移箭头尖端与箭头线FabricJS,canvas,html5-canvas,fabricjs,Canvas,Html5 Canvas,Fabricjs,我想做一个函数,让你可以在画布上画一个箭头。到目前为止,我所做的一切都是有效的,但我仍停留在移动时将箭头指向线条末端的计算上。我附上了一张图片,表明角度计算正确 我只需要移动小费,但我想不出来。非常感谢您的帮助 提示:提示是一条路径,但也许有更好的解决方案 function drawArrowMouseDown( e ) { var mouse = canvas.getPointer(e.e); started = true; lastX = mouse.x;

我想做一个函数,让你可以在画布上画一个箭头。到目前为止,我所做的一切都是有效的,但我仍停留在移动时将箭头指向线条末端的计算上。我附上了一张图片,表明角度计算正确

我只需要移动小费,但我想不出来。非常感谢您的帮助

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

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();
}
函数绘图箭头鼠标向下(e){
var mouse=canvas.getPointer(e.e);
开始=真;
lastX=鼠标.x;
lastY=鼠标。y;
var$color=colors[self.selectedColor]!=未定义的颜色[self.selectedColor]:“红色”;
var line=新织物.line([lastX,lastY,lastX,lastY]{
笔画:$color,
冲程宽度:3,
lockScalingX:对,
lockScalingY:是的,
是的,
哈斯:错,
哈斯:错,
perPixelTargetFind:对,
填充:$color,
strokeLineCap:“圆形”
});
line.lockScalingX=line.lockScalingY=true;
var tip=新结构路径('M 0 0 L-20 15 M 0 0 L 20 15 z'{
左:lastX,
上图:拉斯蒂,
冲程宽度:3,
笔划:“蓝色”,
strokeLineCap:‘圆形’,
哈斯:错,
原文:“中心”,
原创:“中心”
});
tip.line=直线;
line.tip=tip;
canvas.add(行);
画布。添加(提示);
提示:bringToFront();
canvas.setActiveObject(行);
canvas.renderAll();
}
函数drawArrowMouseMove(e){
如果(!已启动){
返回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');
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角;
如果(x==0){
如果(y==0){
角度=0;
}
如果(y>0),则为else{
角度=Math.PI/2;
}
否则{
角度=数学PI*3/2;
}
}
如果(y==0),则为else{
如果(x>0){
角度=0;
}
否则{
角度=Math.PI;
}
}
否则{
if(x<0){
角度=Math.atan(y/x)+Math.PI;
}
else if(y<0){
角度=Math.atan(y/x)+(2*Math.PI);
}
否则{
角度=数学坐标(y/x);
}
}
角度=角度*180/Math.PI;
尖端设置(“角度”,角度-90);
canvas.renderAll();
}

您的角度计算有点偏差

改为使用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;

谢谢,虽然这不是问题所在,但让代码更高效总是可以的。我不知道如何实现它。角度计算的代码不是我的;我是从另一个答案中得到的。这个片段应该替换什么?