在fabricJS画布上未正确绘制箭头

时间:2016-10-17 14:42:30

标签: javascript html5 canvas position fabricjs

我正在处理一个项目,其中可以在fabricJS画布上绘制多个形状(矩形,三角形,椭圆形,...)。现在我正在实现绘制箭头的功能。此箭头由两个形状组成,一条线和一条三角形(箭头)。它们作为组对象添加到画布中,但问题是在画布上未正确绘制箭头。 (看到 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/

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

亲切的问候,

斯文

1 个答案:

答案 0 :(得分:0)

我认为将线和箭头添加到组然后移动它们会导致一些问题。我移动了代码,以便箭头和线只在绘图完成后才加入一个组,这似乎解决了问题。我所做的基本操作是等到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/