使用管理单元调整大小 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 = 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 destructuring assignment,所以它在 IE 中不起作用。


在调整左边缘的大小时,右边缘似乎仍然有些混乱,但我认为这是四舍五入的错误...?

即使没有,我希望这足以让您入门。