使用管理单元调整大小 interact.js
Resizing with snap in interact.js
在这个 jsFiddle 中,我有一个 interact.js 矩形,可以使用 10px x 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 = 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 中不起作用。
在调整左边缘的大小时,右边缘似乎仍然有些混乱,但我认为这是四舍五入的错误...?
即使没有,我希望这足以让您入门。
在这个 jsFiddle 中,我有一个 interact.js 矩形,可以使用 10px x 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 = 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 中不起作用。
在调整左边缘的大小时,右边缘似乎仍然有些混乱,但我认为这是四舍五入的错误...?
即使没有,我希望这足以让您入门。