我正在画布中创建一个具有一定宽度和高度的形状(此形状是剪裁矩形)。然后在这个形状内,我正在加载一个可以移动和旋转的物体。 我编写了一个自定义函数,用于获取此形状内的中心点,如果对象不旋转,它的效果很好。 如果我将此对象旋转超过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>
要重现我的问题,请单击“旋转”,然后单击“居中”按钮,您将看到该形状在剪切矩形之外向上移动。
如果物体没有旋转,居中工作正常。
有没有办法修复我的居中功能或在剪辑矩形内使用“centerV”功能?
此致
答案 0 :(得分:3)
如果您想将对象置于另一个对象中心,最安全的做法是:
获取容器的中心点
在该点设置对象的中心点
可以等于:
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();
};
&#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;