啊,我看到了问题。这是发生的事情:当调整矩形的大小时,您将四舍五入大小和位置。这具有以下效果:
- 你有一个矩形,它的边从
x = 95 到x = 115。它的左侧移动了-3 个单位。现在是92 到115。
- 您检查宽度:宽度是
115 - 92 = 23 单位,因此您四舍五入到最接近的十位:20 单位。
- 您检查位置:它位于
92,因此您将其移动到90。 这会将已调整大小的整个矩形滑过。
您需要以不同于right 和bottom 情况的方式处理top 和left 情况,因为前两种情况会在其大小之上更新矩形位置。最重要的是,您只需要对已更改的相应边进行舍入:您不想在向右移动时将底部舍入。
- 对于
left 或top...
- 将
x 或y 移动到新位置,四舍五入
-
不要围绕
width 或height,因为这会移动right 或bottom
- 对于
right 或bottom...
- 不要对
x 或y 执行任何操作,因为对它们进行四舍五入会使整个矩形超出
- 好吧,我们仍然可以更改
x 或 y,因为它们将为零,但我们无法舍入它们!
-
仅更改
width 或hight,但这次要四舍五入
要检查的情况很多,但是通过使用函数,这并不难看出它是如何工作的:
.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 destructuring assignment,所以它在IE中不起作用。
调整左边缘的大小时,右边缘似乎仍然有些卡顿,但我认为这是舍入错误...?
即使没有,我希望这足以让你开始。