gpt4 book ai didi

javascript - Fabricjs 在调整大小时捕捉到网格

转载 作者:行者123 更新时间:2023-11-30 07:13:13 27 4
gpt4 key购买 nike

我在尝试让对象根据网格大小调整大小时遇到​​了一些问题。

这是我的 fiddle :http://jsfiddle.net/csh6c6fw/1/

这是我正在应用的代码:

canvas.on('object:scaling', (options) => {
var newWidth = (Math.round(options.target.getWidth() / grid)) * grid;
var newHeight = (Math.round(options.target.getHeight() / grid)) * grid;

if (options.target.getWidth() !== newWidth) {
options.target.set({ width: newWidth, height: newHeight });
}

});

预期结果

它应该像运动一样捕捉到网格。

最佳答案

可能看起来很复杂,但是,以下将完成工作:

canvas.on('object:scaling', options => {
var target = options.target,
w = target.width * target.scaleX,
h = target.height * target.scaleY,
snap = { // Closest snapping points
top: Math.round(target.top / grid) * grid,
left: Math.round(target.left / grid) * grid,
bottom: Math.round((target.top + h) / grid) * grid,
right: Math.round((target.left + w) / grid) * grid
},
threshold = grid,
dist = { // Distance from snapping points
top: Math.abs(snap.top - target.top),
left: Math.abs(snap.left - target.left),
bottom: Math.abs(snap.bottom - target.top - h),
right: Math.abs(snap.right - target.left - w)
},
attrs = {
scaleX: target.scaleX,
scaleY: target.scaleY,
top: target.top,
left: target.left
};
switch (target.__corner) {
case 'tl':
if (dist.left < dist.top && dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.top = target.top + (h - target.height * attrs.scaleY);
attrs.left = snap.left;
} else if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.left = attrs.left + (w - target.width * attrs.scaleX);
attrs.top = snap.top;
}
break;
case 'mt':
if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.top = snap.top;
}
break;
case 'tr':
if (dist.right < dist.top && dist.right < threshold) {
attrs.scaleX = (snap.right - target.left) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.top = target.top + (h - target.height * attrs.scaleY);
} else if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.top = snap.top;
}
break;
case 'ml':
if (dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.left = snap.left;
}
break;
case 'mr':
if (dist.right < threshold) attrs.scaleX = (snap.right - target.left) / target.width;
break;
case 'bl':
if (dist.left < dist.bottom && dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.left = snap.left;
} else if (dist.bottom < threshold) {
attrs.scaleY = (snap.bottom - target.top) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.left = attrs.left + (w - target.width * attrs.scaleX);
}
break;
case 'mb':
if (dist.bottom < threshold) attrs.scaleY = (snap.bottom - target.top) / target.height;
break;
case 'br':
if (dist.right < dist.bottom && dist.right < threshold) {
attrs.scaleX = (snap.right - target.left) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
} else if (dist.bottom < threshold) {
attrs.scaleY = (snap.bottom - target.top) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
}
break;
}
target.set(attrs);
});

这是一个工作示例:

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

// create grid
for (var i = 0; i < (600 / grid); i++) {
canvas.add(new fabric.Line([i * grid, 0, i * grid, 600], {
stroke: '#ccc',
selectable: false
}));
canvas.add(new fabric.Line([0, i * grid, 600, i * grid], {
stroke: '#ccc',
selectable: false
}))
}

// add objects
canvas.add(new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: '#faa',
originX: 'left',
originY: 'top',
centeredRotation: true
}));

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

// snap to grid
canvas.on('object:moving', options => {
options.target.set({
left: Math.round(options.target.left / grid) * grid,
top: Math.round(options.target.top / grid) * grid
});
});

canvas.on('object:scaling', options => {
var target = options.target,
w = target.width * target.scaleX,
h = target.height * target.scaleY,
snap = { // Closest snapping points
top: Math.round(target.top / grid) * grid,
left: Math.round(target.left / grid) * grid,
bottom: Math.round((target.top + h) / grid) * grid,
right: Math.round((target.left + w) / grid) * grid
},
threshold = grid,
dist = { // Distance from snapping points
top: Math.abs(snap.top - target.top),
left: Math.abs(snap.left - target.left),
bottom: Math.abs(snap.bottom - target.top - h),
right: Math.abs(snap.right - target.left - w)
},
attrs = {
scaleX: target.scaleX,
scaleY: target.scaleY,
top: target.top,
left: target.left
};
switch (target.__corner) {
case 'tl':
if (dist.left < dist.top && dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.top = target.top + (h - target.height * attrs.scaleY);
attrs.left = snap.left;
} else if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.left = attrs.left + (w - target.width * attrs.scaleX);
attrs.top = snap.top;
}
break;
case 'mt':
if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.top = snap.top;
}
break;
case 'tr':
if (dist.right < dist.top && dist.right < threshold) {
attrs.scaleX = (snap.right - target.left) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.top = target.top + (h - target.height * attrs.scaleY);
} else if (dist.top < threshold) {
attrs.scaleY = (h - (snap.top - target.top)) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.top = snap.top;
}
break;
case 'ml':
if (dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.left = snap.left;
}
break;
case 'mr':
if (dist.right < threshold) attrs.scaleX = (snap.right - target.left) / target.width;
break;
case 'bl':
if (dist.left < dist.bottom && dist.left < threshold) {
attrs.scaleX = (w - (snap.left - target.left)) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
attrs.left = snap.left;
} else if (dist.bottom < threshold) {
attrs.scaleY = (snap.bottom - target.top) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
attrs.left = attrs.left + (w - target.width * attrs.scaleX);
}
break;
case 'mb':
if (dist.bottom < threshold) attrs.scaleY = (snap.bottom - target.top) / target.height;
break;
case 'br':
if (dist.right < dist.bottom && dist.right < threshold) {
attrs.scaleX = (snap.right - target.left) / target.width;
attrs.scaleY = (attrs.scaleX / target.scaleX) * target.scaleY;
} else if (dist.bottom < threshold) {
attrs.scaleY = (snap.bottom - target.top) / target.height;
attrs.scaleX = (attrs.scaleY / target.scaleY) * target.scaleX;
}
break;
}
target.set(attrs);
});
canvas {border: 1px solid #ccc}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

关于javascript - Fabricjs 在调整大小时捕捉到网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44147762/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com