我在我的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();
}
});
这是有效的,但是当我缩放形状时,中心点会改变它的协调性。
答案 0 :(得分:1)
如果我理解正确的话,应该这样做:
对您的代码进行小调整(相关部分):
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;
}
});