fabricJS 上的箭头未正确绘制 canvas

Arrow is not drawn correctly on fabricJS canvas

我正在开发一个项目,其中可以在 fabricJS 上绘制多个形状(矩形、三角形、椭圆......)canvas。现在我正在实现绘制箭头的功能。这个箭头由两种形状组成,一条线和一个三角形(箭头)。它们作为组对象添加到 canvas,但问题是 canvas 上的箭头绘制不正确。 (看 this picture).

下面是我绘制箭头的代码:

drawShape: function(canvas, shape) {

        let selectedShape;
        let pointer, startX, startY, origX, origY;
        let rect, ellipse, line, triangle, arrow;

        let stroke = 'black';
        let fill = 'transparent';

 canvas.on('mouse:down', function(option) {

    if(option.target != null) {
         return;
    } else {

         switch(shape)
         {

           case 'arrow' :

             pointer = canvas.getPointer(option.e);                         
             let arrowLinePoints = [pointer.x, pointer.y, pointer.x, pointer.y];

             startX = pointer.x;
             startY = pointer.y;

             line = new fabric.Line(arrowLinePoints, {
                 top: startY,
                 left: startX,
                 fill: fill,
                 stroke: stroke,
             });

             // reference points for arrowhead
             origX = line.x2;
             origY = line.y2;

             let dx = line.x2 - line.x1,
                 dy = line.y2 - line.y1;

             /* calculate angle of arrow */
             let angle = Math.atan2(dy, dx);
             angle *= 180 / Math.PI;
             angle += 90;

             arrow = new fabric.Triangle({
                 angle: angle,
                 fill: 'black',
                 top: line.y2,
                 left: line.x2,
                 width: 1,
                 height: 1,
                 originX: 'center',
                 originY: 'center',
                 stroke: stroke
             });


              let grp = new fabric.Group([line, arrow], {
                 top: startY,
                 left: startX,
                 width: 1,
                 height: 1,
                 hasBorders: true,
                 hasControls: true,
              });

              selectedShape = grp;

              break;

      }

      canvas.add(selectedShape);  


      canvas.on("mouse:move", function(option) {

            switch(shape) {

              case 'arrow' :
                   pointer = canvas.getPointer(option.e);     

                   selectedShape.set({
                       width: Math.abs(startX -pointer.x),
                       height: Math.abs(startY - pointer.y)
                   });
                   selectedShape.setCoords();                        

                   line = selectedShape.item(0);
                   line.set({
                        x2: pointer.x, 
                        y2: pointer.y,
                        left: selectedShape.left,
                        top: selectedShape.top
                    });
                    line.setCoords();

                     let dx = line.x2 - line.x1,
                         dy = line.y2 - line.y1;

                      let angle = Math.atan2(dy, dx);
                      angle *= 180 / Math.PI;
                      angle += 90;

                      arrow = selectedShape.item(1);
                      arrow.set({
                               top: line.y2, 
                               left: line.x2, 
                               angle: angle,
                               width: 15, 
                               height: 15
                       });  
                       arrow.setCoords();

                       canvas.renderAll();

                       break;
               }
  });  

canvas.on('mouse:up', function() {

   canvas.off('mouse:move');                      
});

JSFiddle:https://jsfiddle.net/9408k1gb/

有办法解决这个问题吗? 提前致谢!

亲切的问候,

斯文

我认为将线条和箭头添加到组中然后四处移动会导致一些问题。我移动了代码,以便箭头和线条仅在绘图完成后才加入到一个组中,这似乎解决了问题。我所做的基本工作是等到 mouse:up 事件,然后像这样照顾小组:

canvas.deactivateAll();
canvas.remove(line);
canvas.remove(arrow);
selectedShape = new fabric.Group([line, arrow], {
    hasBorders: true,
    hasControls: true,
});
canvas.add(selectedShape);

https://jsfiddle.net/9408k1gb/1/