如何在 FabricJS 的父对象中心创建对象?

How to create object stick on center of parent object in FabricJS?

我有一个对象,例如圆,我想在必须居中对齐的父圆的边界上添加更多圆。

在附加的 gif 图像上,您可以看到我的光标 - 它只允许我在父级的边界上创建一个子级圆圈。

到目前为止,我只能创建父圈子。

var circle = new fabric.Circle({
        strokeWidth: 1,
        stroke: "#222",
        noScaleCache: false,
        strokeUniform: true,
        scaleX: 1,
        scaleY: 1,
        left: canvas.getWidth() / 2,
        top: canvas.getHeight() / 2,
        radius: fabric.util.parseUnit(circleSize + 'in')
    });

基本上你需要计算你想画的圆和主圆之间的欧几里得距离,如果距离接近主圆的边界你就在鼠标点击的位置画一个圆.

使用Math.hypot函数计算距离。

这是代码。

var canvas = new fabric.Canvas('c', {
  selection: false
});

var circleRadius = 100;

var c = new fabric.Circle({
  strokeWidth: 3,
  stroke: "#222",
  fill: "#55ff55",
  noScaleCache: false,
  strokeUniform: true,
  selectable: false,
  scaleX: 1,
  scaleY: 1,
  left: canvas.getWidth() / 2 - circleRadius,
  top: canvas.getHeight() / 2 - circleRadius,
  radius: circleRadius
});

canvas.add(c);

var circleAngle = Math.atan2(c.getCenterPoint().x,c.getCenterPoint().y);
var circle = new fabric.Circle({
  strokeWidth: 3,
  stroke: "#222",
  radius: 30,
  selectable: true,
  originX: 'center',
  originY: 'center',
  fill: "#ff5555ff",
  left: Math.sin(circleAngle) * circleRadius + canvas.getWidth() / 2,
  top: Math.cos(circleAngle) * circleRadius + canvas.getHeight() / 2
});

canvas.add(circle);

var isDown, origX, origY;

canvas.on('mouse:down', function(o) {
  var pointer = canvas.getPointer(o.e);
  origX = pointer.x;
  origY = pointer.y;
  if (isDown) {
    circle.set({
      strokeWidth: 3,
      stroke: "#222",
      radius: 30,
      left: pointer.x,
      top: pointer.y,
      fill: "#ff5555ff"
    });
    canvas.add(circle);
    circle = new fabric.Circle({
      strokeWidth: 3,
      stroke: "#222",
      radius: 1,
      selectable: true,
      originX: 'center',
      originY: 'center'
    });
    canvas.add(circle);
  }
});

canvas.on('mouse:move', function(o) {
  var pointer = canvas.getPointer(o.e);
  var x = pointer.x - c.getCenterPoint().x;
  var y = pointer.y - c.getCenterPoint().y;
  circle.set({
    strokeWidth: 3,
    stroke: "#222",
    radius: 30,
    left: Math.sin(Math.atan2(x,y))*c.radius + canvas.getWidth() / 2,
    top: Math.cos(Math.atan2(x,y))*c.radius + canvas.getHeight() / 2,
    fill: "#ff5555ff"
  });

  if (nearToBorder(pointer, c.getCenterPoint(), c.radius)) {
    isDown = true;
  } else {
    isDown = false;
  }
  canvas.renderAll();
});

canvas.on('mouse:up', function(o) {
  isDown = false;
});

function nearToBorder(pointer, circlePoint, r) {
  var d = Math.hypot(pointer.x - (circlePoint.x), pointer.y - (circlePoint.y));
  return d >= r - 10 && d <= r + 10;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.0.0-rc.1/fabric.min.js"></script>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>