Fabri cJS Я хочу создать стикер объекта в центре родительского объекта - PullRequest
0 голосов
/ 12 июля 2020

У меня есть объект, например круг, и я хочу добавить больше кругов на границе родительского круга, который должен быть выровнен по центру.

На прикрепленном изображении 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')
    });

1 Ответ

2 голосов
/ 12 июля 2020

В основном вам нужно рассчитать евклидово расстояние между кругом, который вы хотите нарисовать, и основным кругом, и если расстояние близко к границе основного круга, вы просто рисуете круг в том месте, где вы щелкнули.

Расстояние рассчитывается с помощью функции 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>
...