【问题标题】:Draw an arrow that is always pointing away from an object绘制一个始终指向远离对象的箭头
【发布时间】:2019-01-27 07:02:20
【问题描述】:

我有一个画布,上面有一个圆圈和一个三角形,用一条线连接它们。我正在尝试将三角形用作箭头。如果移动任何一个对象,我希望箭头始终指向远离圆心。我以为我可以使用线的角度来旋转三角形,但结果并不令人满意,我确定我的方法是错误的。

有解决此问题的建议或技巧吗?在我链接的 JSFiddle 中,您可以移动任一对象并旋转三角形的角度,但它永远不会完全正确:

https://jsfiddle.net/zh1bkfs5/

const c = new fabric.Canvas('c');
c.preserveObjectStacking = true;

function radiansToDegrees (radians) {
  return radians * 180 / Math.PI;
}

function calcAngle (opposite, adjacent) {
  return radiansToDegrees(Math.atan(opposite / adjacent));
}

function syncObjects (e) {

  const x1 = triangle.left;
  const y1 = triangle.top;
  const x2 = circle.left + circle.radius;
  const y2 = circle.top + circle.radius;

  line.set('x1', x1);
  line.set('y1', y1);
  line.set('x2', x2);
  line.set('y2', y2);

  const angle = calcAngle(y2 - y1, x1 - x2);

  triangle.set('angle', -angle);
  triangle.setCoords();

  c.renderAll();
}

const circle = new fabric.Circle({
  fill: 'black',
  radius: 20,
  top: 100,
  left: 100,
  hasBorders: false,
  hasControls: false
});

const triangle = new fabric.Triangle({
  fill: 'orange',
  height: 20,
  width: 20,
  top: 50,
  left: 120,
  hasBorders: false,
  hasControls: false,
  originX: 'center',
  originY: 'center'
});

const coords = [
  triangle.left,
  triangle.top,
  circle.left + circle.radius,
  circle.top + circle.radius
];

const line = new fabric.Line(coords, {
  stroke: 'orange',
  strokeWidth: 1,
  selectable: false
});

c.add(circle, line, triangle);

c.on('object:moving', syncObjects);

【问题讨论】:

    标签: javascript graphics fabricjs


    【解决方案1】:

    在更新我不再需要反转角度后,我将“相邻”和“相反”的值翻转。我现在已经完成了 99%,只是遇到了一个三角形有时会以错误的方式翻转但应该很容易修复的情况,至少我最初的方法有效。

    更新:https://jsfiddle.net/zh1bkfs5/1/

    const c = new fabric.Canvas('c');
    c.preserveObjectStacking = true;
    
    function radiansToDegrees (radians) {
      return radians * 180 / Math.PI;
    }
    
    function calcAngle (opposite, adjacent) {
      return radiansToDegrees(Math.atan(opposite / adjacent));
    }
    
    function syncObjects (e) {
    
      const x1 = triangle.left;
      const y1 = triangle.top;
      const x2 = circle.left + circle.radius;
      const y2 = circle.top + circle.radius;
    
      line.set('x1', x1);
      line.set('y1', y1);
      line.set('x2', x2);
      line.set('y2', y2);
    
      const angle = calcAngle(x1 - x2, y2 - y1);
    
      triangle.set('angle', angle);
      triangle.setCoords();
    
      c.renderAll();
    }
    
    const circle = new fabric.Circle({
      fill: 'black',
      radius: 20,
      top: 100,
      left: 100,
      hasBorders: false,
      hasControls: false
    });
    
    const triangle = new fabric.Triangle({
      fill: 'orange',
      height: 20,
      width: 20,
      top: 50,
      left: 120,
      hasBorders: false,
      hasControls: false,
      originX: 'center',
      originY: 'center'
    });
    
    const coords = [
      triangle.left,
      triangle.top,
      circle.left + circle.radius,
      circle.top + circle.radius
    ];
    
    const line = new fabric.Line(coords, {
      stroke: 'orange',
      strokeWidth: 1,
      selectable: false
    });
    
    c.add(circle, line, triangle);
    
    c.on('object:moving', syncObjects);
    

    【讨论】:

      【解决方案2】:

      将你的syncObject函数的一部分更改为:

      const x = x1 - x2;
      const y = y2 - y1;
      const angle = calcAngle(x, y);
      if(x < 0 && y > 0 || x > 0 && y > 0) {
         triangle.set('angle', angle);
      } else if(x < 0 && y < 0) {
         triangle.set('angle', 180 + angle);
      } if(x > 0 && y < 0) {
         triangle.set('angle', -180 + angle);
      }
      

      这应该可以。你更新的小提琴https://jsfiddle.net/zh1bkfs5/30/

      【讨论】:

      • 啊,完美!谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 2018-11-22
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      相关资源
      最近更新 更多