使用FabricJS

时间:2017-03-26 03:21:09

标签: javascript fabricjs

我在我的canva中心创建了一条垂直线,我希望我的形状可以通过它的中心对齐,当它接近它时就在线上(用户可以接受它)如果他不想对齐的话。

我的JSFiddle存在问题:https://jsfiddle.net/z0u05hee/5/

问题在于,当形状移动时,它会在线条中心附近停留,我无法再将其取出。

这是我的FabricJS代码:

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

var line9 = new fabric.Line([
  canvas.width / 2, 0,
  canvas.width / 2, canvas.width
],{
  stroke: 'green',
})

line9.selectable = false;
line9.evented = false;
canvas.add(line9);

canvas.add(new fabric.Circle({ 
  left: 10, 
  top: 100, 
  radius: 50, 
  fill: '#9f9', 
  originX: 'left', 
  originY: 'top',
  centeredRotation: true
}));

canvas.on('object:moving', function(options) {
    if (Math.round(options.target.left) < (canvas.width / 2) - 15 ||
    Math.round(options.target.left) > (canvas.width / 2) + 15) {
      options.target.set({
        left: Math.round(canvas.width / 2),
      }).setCoords();
    }
});

我该如何修复我的代码?

更新:

canvas.on('object:moving', function(options) {
    if (Math.round(options.target.left) >= (canvas.getActiveObject().getWidth()) - 20 && Math.round(options.target.left) <= (canvas.getActiveObject().getWidth()) + 20) {
      options.target.set({
        left: (canvas.width / 2) - canvas.getActiveObject().getWidth() / 2,
      }).setCoords();
    }
});

这是有效的,但是当我缩放形状时,中心点会改变它的协调性。

3 个答案:

答案 0 :(得分:1)

如果我理解正确的话,应该这样做:

fabricjs snap to grid

对您的代码进行小调整(相关部分):

var snapZone = 15;
canvas.on('object:moving', function(options) {
  var objectMiddle = options.target.left + options.target.getWidth() / 2;
  if (objectMiddle > canvas.width / 2 - snapZone &&
    objectMiddle < canvas.width / 2 + snapZone) {
    options.target.set({
      left: canvas.width / 2 - options.target.getWidth() / 2,
    }).setCoords();
  }
});

所有重要的JSFiddle更新,https://jsfiddle.net/rekrah/9k9hd49u/

答案 1 :(得分:1)

Tims 的回答是正确的,但如果您旋转对象,它将不起作用。 我找到了解决这个问题的方法:

  const objectMiddleFromLeft = object.getCenterPoint().x;
  const objectMiddleFromTop = object.getCenterPoint().y;

  object.setPositionByOrigin(
    {
      x:
        objectMiddleFromLeft > canvas.width / 2 - 15 &&
        objectMiddleFromLeft < canvas.width / 2 + 15
          ? canvas.width / 2
          : objectMiddleFromLeft,
      y:
        objectMiddleFromTop > canvas.height / 2 - 15 &&
        objectMiddleFromTop < canvas.height / 2 + 15
          ? canvas.height / 2
          : objectMiddleFromTop,
    },
    "center",
    "center"
  );

答案 2 :(得分:0)

在将对象放在画布上后调整画布大小时,事情会稍微复杂一些。 无论出于何种原因,fabric js 都会在视口坐标中返回 canvas.width,即当您调整大小时,宽度会发生变化。 然而 object.width 不受画布调整大小的影响,因此保持不变。 在调整画布大小和/或调整对象大小后,以下代码段对我有用。如果有人有更简单的解决方案来实现这一点 - 请分享!

// Snapping while moving
canvas.on('object:moving', options => {
  const obj = options.target;

  // snap only if the object is upright
  if (obj.angle !== 0) {
    return;
  }
  
  // Capture area of snap
  let snap = 10;
  // Compensate snap size for transform
  const mySnap = snap / canvas.viewportTransform[0];

  // Sets corner position coordinates based on current angle, width and height
  obj.setCoords();

  // Snap left
  if (Math.abs(obj.oCoords.tl.x) < mySnap) {
    obj.left = 0;
  }
  // Snap right
  else if (Math.abs(obj.aCoords.tr.x - canvas.vptCoords.tr.x) < mySnap) {
    let canvasVptWidth = canvas.vptCoords.tr.x;
    obj.left = canvasVptWidth - obj.getScaledWidth();
  }
  // Snap center horizontally
  else if (Math.abs(obj.oCoords.mt.x - canvas.width / 2) < mySnap) {
    canvasVptWidth = canvas.vptCoords.br.x;
    obj.left = (canvasVptWidth - obj.getScaledWidth()) / 2;
  }

  // Snap top
  if (Math.abs(obj.aCoords.tl.y) < mySnap) {
    obj.top = 0;
  }
  // Snap bottom
  else if (Math.abs(obj.aCoords.br.y - canvas.vptCoords.br.y) < mySnap) {
    let canvasVptHeight = canvas.vptCoords.br.y;
    obj.top = canvasVptHeight - obj.getScaledHeight();
  }
  // Snap center vertically
  else if (Math.abs(obj.oCoords.ml.y - canvas.height / 2) < mySnap) {
    canvasVptHeight = canvas.vptCoords.br.y;
    obj.top = (canvasVptHeight - obj.getScaledHeight()) / 2;
  }
});