使用管理单元interact.js调整大小



在这个jsFiddle中,我有一个interact.js rect,它可以通过10px乘以10px的快照来调整大小。rect位于x=95px,当我将左侧向左移动时,它将移动到x=90x。这很好,但右侧也会向右移动,不应该。

这个代码出了什么问题?rect有句柄,这是造成问题的原因吗?

.on('resizemove', function(event) {
const target = event.target.querySelector('rect');
for (const attr of ['width', 'height']) {
let v = Number(target.getAttribute(attr));
v += event.deltaRect[attr];
target.setAttribute(attr, Math.round(v/10)*10);
}
for (const attr of ['top', 'left']) {
const a = attr == 'left' ? 'x' : 'y';
let v = Number(target.getAttribute(a));
v += event.deltaRect[attr];
target.setAttribute(a, Math.round(v/10)*10);
}
findLocations(rect, handles);

});

啊,我看到问题了。发生的情况是:当调整矩形的大小时,您将对大小和位置进行四舍五入。这具有以下效果:

  • 有一个矩形,它的边从x = 95x = 115。它的左侧移动了-3单元。现在是92115
  • 检查宽度:宽度为115 - 92 = 23个单位,因此四舍五入到最接近的十位:20个单位
  • 你检查一下位置:它在92上,所以你把它移到90这将滑动整个已调整大小的矩形

您需要处理与rightbottom不同的topleft情况,因为前两种情况会更新其大小顶部的矩形位置。最重要的是,你只需要绕过被改变的一侧:当你向右移动时,你不想绕过底部。

  • 对于lefttop。。。
    • xy移动到新位置,四舍五入
    • 不要绕过widthheight,因为这会移动rightbottom
  • 对于rightbottom。。。
    • xy不执行任何操作,因为四舍五入会移动整个矩形
    • 好吧,我们仍然可以更改xy,因为它们将为零,但我们不能将它们四舍五入
    • 更改widthhight,但此时四舍五入

这是很多需要检查的情况,但通过使用一个函数,不难看出它是如何工作的:

.on('resizemove', function(event) {
const target = event.target.querySelector('rect');
function changeVal(attr, change, round) {
let val = Number(target.getAttribute(change));
val += event.deltaRect[attr];
if (round) val = Math.round(val / 10) * 10;
target.setAttribute(change, val);
}
let round = false;
if (event.deltaRect.top != 0) round = true;
changeVal('top', 'y', round);
round = false;
if (event.deltaRect.left != 0) round = true;
changeVal('left', 'x', round);
round = false;
if (event.deltaRect.right != 0) round = true;
changeVal('width', 'width', round);
round = false;
if (event.deltaRect.bottom != 0) round = true;
changeVal('height', 'height', round);
findLocations(rect, handles);
});

缩短并更改为与以前相同的循环样式:

.on('resizemove', function(event) {
const target = event.target.querySelector('rect');
const attributes = [
{ check: 'top', change: 'y' },
{ check: 'left', change: 'x' },
{ check: 'right', change: 'width' },
{ check: 'bottom', change: 'height' }
];
for (const {check, change} of attributes) {
let val = Number(target.getAttribute(change));
val += event.deltaRect[check];
if (event.deltaRect[check]) val = Math.round(val / 10) * 10;
target.setAttribute(change, val);
}
findLocations(rect, handles);
});

这使用了ES6析构函数赋值,所以它在IE中不起作用。


调整左边缘的大小时,右边缘似乎仍然有一些刺耳的声音,但我认为这是舍入的错误。。。?

即使没有,我希望这足以让你开始。

最新更新