javascript - FabricJS - 为什么形状内的旋转对象不垂直居中?

标签 javascript canvas fabricjs

我正在 Canvas 内创建一个具有一定宽度和高度的形状(该形状是一个剪切矩形)。然后在这个形状内我加载一个可以移动和旋转的对象。 我编写了一个自定义函数来获取此形状内的中心点,如果对象不旋转,它效果很好。 如果我将此对象旋转超过 90 度并单击“中心”按钮 - 该对象将向上移动到剪切矩形之外。

我无法使用 native FabricJs“centerV”函数,因为我希望该对象将在剪切矩形内居中 - 而不是 Canvas 容器,所以这就是我创建变量“objectVerticalCenter”的原因。

我的代码如下:

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

var clippingRect = new fabric.Rect({
  left: 170,
  top: 90,
  width: 185,
  height: 400,
  fill: 'transparent',
  stroke: 1,
  opacity: 1,
  hasBorders: false,
  hasControls: false,
  hasRotatingPoint: false,
  selectable: false,
  preserveObjectStacking: true,
  objectCaching: false
});

var retinaScalling = canvas.getRetinaScaling();

var pol = new fabric.Polygon([{
  x: 200,
  y: 0
}, {
  x: 250,
  y: 50
}, {
  x: 250,
  y: 100
}, {
  x: 150,
  y: 100
}, {
  x: 150,
  y: 50
}], {
  left: 250,
  top: 150,
  angle: 0,
  fill: 'green'
});

pol.scaleX = 0.5;
pol.scaleY = 0.5;
pol.set('id', 'shape');
pol.scaleToWidth(clippingRect.getWidth());
pol.setCoords();
pol.clipTo = function(ctx) {
  ctx.save();
  ctx.setTransform(retinaScalling, 0, 0, retinaScalling, 0, 0);
  clippingRect.render(ctx);
  ctx.restore();
};
canvas.centerObjectH(pol);
canvas.add(pol);
canvas.renderAll();
canvas.setActiveObject(pol);
canvas.add(pol);
canvas.renderAll();

document.getElementById('rotate').onclick = function() {
  var activeObject = canvas.getActiveObject();
  activeObject.setAngle(200);
  activeObject.setCoords();
  canvas.renderAll();
};

document.getElementById('center').onclick = function() {
  var activeObject = canvas.getActiveObject();
  var rectHeight = activeObject.getBoundingRectHeight();
  var objectVerticalCenter = (clippingRect.getHeight() / 2) - (rectHeight / 2) + clippingRect.top;

  activeObject.set('top', objectVerticalCenter);
  activeObject.setCoords();
  canvas.renderAll();
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<button id="rotate">Rotate</button>
<button id="center">Center</button>
<canvas id="canvas" width="530" height="600"></canvas>

JSFiddle

要重现我的问题,您必须单击“旋转”,然后单击“居中”按钮,您将看到形状向上移动到剪切矩形之外。

如果对象没有旋转,居中效果很好。

有什么方法可以修复我的居中功能或在剪切矩形内使用“centerV”功能的方法吗?

问候

最佳答案

如果您想将一个对象置于另一个对象的中心,最安全的做法是:

  • 获取容器的中心点

  • 将对象的中心点设置在该点

在代码中这可能等于:

var clipCenter = clippingRect.getCenterPoint();
activeObject.setPositionByOrigin(clipCenter,'center','center');

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

        var clippingRect = new fabric.Rect({
          left: 170,
          top: 90,
          width: 185,
          height: 400,
          fill: 'transparent',
          stroke: 1,
          opacity: 1,
          hasBorders: false,
          hasControls: false,
          hasRotatingPoint: false,
          selectable: false,
          preserveObjectStacking: true,
          objectCaching: false
        });

        var retinaScalling = canvas.getRetinaScaling();

        var pol = new fabric.Polygon([{
          x: 200,
          y: 0
        }, {
          x: 250,
          y: 50
        }, {
          x: 250,
          y: 100
        }, {
          x: 150,
          y: 100
        }, {
          x: 150,
          y: 50
        }], {
          left: 250,
          top: 150,
          angle: 0,
          fill: 'green'
        });

        pol.scaleX = 0.5;
        pol.scaleY = 0.5;
        pol.set('id', 'shape');
        pol.scaleToWidth(clippingRect.getWidth());
        pol.setCoords();
        pol.clipTo = function(ctx) {
          ctx.save();
          ctx.setTransform(retinaScalling, 0, 0, retinaScalling, 0, 0);
          clippingRect.render(ctx);
          ctx.restore();
        };
        canvas.centerObjectH(pol);
        canvas.setActiveObject(pol);
        canvas.add(pol);
        canvas.renderAll();



        document.getElementById('rotate').onclick = function() {
          var activeObject = canvas.getActiveObject();
          activeObject.setAngle(200);
          activeObject.setCoords();
          canvas.renderAll();
        };

        document.getElementById('center').onclick = function() {
          var activeObject = canvas.getActiveObject();
          var clipCenter = clippingRect.getCenterPoint();
   activeObject.setPositionByOrigin(clipCenter,'center','center');
          canvas.renderAll();
        };
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<button id="rotate">Rotate</button>
<button id="center">Center</button>
<canvas id="canvas" width="530" height="600"></canvas>

关于javascript - FabricJS - 为什么形状内的旋转对象不垂直居中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48185123/

相关文章:

javascript - getContext(2d) & drawImage > toDataURL > undefiend 问题

javascript - 如何选择颜色,将其填充到使用fabric.js在 Canvas 中上传的选定图像中?

javascript - 使用 Fabricjs 时如何在调整 Canvas 元素大小时防止内容缩放

javascript - 如何更改页面 Load "jquery"属性中给出的 Divs CSS 背景

Javascript库d3调用函数

java - J2ME 游戏 Canvas

Android游戏循环,如何控制速度

javascript - 在fabric js中,如何从图像对象中获取原始图像源

javascript - 如何在点击按钮后进入休眠状态

HTML Canvas 水平翻转仅在每秒单击一次时有效