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

时间:2018-01-10 10:19:58

标签: javascript canvas fabricjs

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

我不能使用原生FabricJs“centerV”函数,因为我希望该对象将在剪切矩形内部居中 - 而不是画布容器,这就是我创建变量“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”功能?

此致

1 个答案:

答案 0 :(得分:3)

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

  • 获取容器的中心点

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

代码中的

可以等于:

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

&#13;
&#13;
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();
        };
&#13;
<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>
&#13;
&#13;
&#13;