【问题标题】:Resizing a rotated item with javascript (interact.js)使用 javascript (interact.js) 调整旋转项目的大小
【发布时间】:2018-04-10 16:11:52
【问题描述】:

我花了很多天时间尝试使一个项目可调整大小,并使用interact.js 旋转。

这是我目前拥有的代码,我将尝试解释这个概念。

我们有一个选择器项有两个原因,因为容器可以通过 css 转换(如缩放)进行缩放,我们需要将选择器放在外面,因为我们有一个多选,如果我有两个,选择器会增长矩形选择,但在这种情况下,这不是主要问题,我们已经计算了缩放比例,没有问题和其他事情。

选择器调整大小时,取矩形,宽度、高度、左、上、旋转都一样。

Javascript:

// TAP - CLICK EVENT (just for positioning the selector)
interact('#rectangle').on('tap', event => {
  console.log('Tap Box!');
  event.stopPropagation();
  const $rectangleCloned = $('#rectangle').clone();
  const previousTransform = $rectangleCloned.css('transform');
  $rectangleCloned.css('transform', 'none');
  $rectangleCloned.css('opacity', '0');
  $rectangleCloned.css('display', 'block');


  $('#container').append($rectangleCloned);
  const values = $rectangleCloned[0].getBoundingClientRect();
  // This is just a trick for fast implementation:
  $('#selector').css('top', values.y);
  $('#selector').css('left', values.x);
  $('#selector').css('width', values.width);
  $('#selector').css('height', values.height);
  $('#selector').css('transform', previousTransform);

  $rectangleCloned.remove();
  return values;
});


interact('.pointer9').draggable({
  max: 1,
  onmove: event => {
    const angleDeg =
      Math.atan2(
        centerRotate.posY - event.pageY,
        centerRotate.posX - event.pageX
      ) *
      180 /
      Math.PI;

    console.log(this.rotate);
    const prevAngle = this.rotate - angleInitial;
    const angle = parseInt(angleDeg) + prevAngle;
    this.$rectangle.css({
      transform: 'rotate(' + angle + 'deg)'
    });
    this.$selector.css({
      transform: 'rotate(' + angle + 'deg)'
    });
  },
  onstart: event => {
    const data = event.interactable.getRect(event.target.parentNode);
    this.centerRotate = {
      posX: data.left + data.width / 2,
      posY: data.top + data.height / 2
    };
    this.angleInitial =
      Math.atan2(
        centerRotate.posY - event.pageY,
        centerRotate.posX - event.pageX
      ) *
      180 /
      Math.PI;
    this.$rectangle = $('#rectangle');
    this.$selector = $('#selector');
    this.rotate = $rectangle.attr('angle') || 0;
  },
  onend: event => {
    const $box = $('#selector');
    const matrix = $box.css('transform');
    const values = matrix
      .split('(')[1]
      .split(')')[0]
      .split(',');

    var a = values[0];
    var b = values[1];
    var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
    $rectangle.attr('angle', angle);

  }
});


interact('#selector')
  .resizable({
    // resize from all edges and corners
    edges: {
      left: true,
      right: true,
      bottom: true,
      top: true
    },

    // keep the edges inside the parent
    restrictEdges: {
      outer: 'parent',
      endOnly: true,
    },

    // minimum size
    restrictSize: {
      min: {
        width: 100,
        height: 50
      },
    },

    inertia: true,
  })
  .on('resizemove', function(event) {
    var target = event.target,
      x = parseFloat($(target).offset().left) || 0,
      y = parseFloat($(target).offset().top) || 0;

    // update the element's style
    target.style.width = event.rect.width + 'px';
    target.style.height = event.rect.height + 'px';

    // translate when resizing from top or left edges
    x += event.deltaRect.left;
    y += event.deltaRect.top;

    target.style.left = x + 'px';
    target.style.top = y + 'px';

    $('#rectangle')[0].style.left = target.style.left;
    $('#rectangle')[0].style.top = target.style.top;

    $('#rectangle')[0].style.width = target.style.width;
    $('#rectangle')[0].style.height = target.style.height;

    target.setAttribute('data-x', x);
    target.setAttribute('data-y', y);

  });

CSS:

#container {
  width: 500px;
  height: 400px;
  top: 0;
  left: 0;
  position: absolute;
  background-color: #CCC;
}

#rectangle {
  top: 50px;
  left: 50px;
  width: 120px;
  height: 60px;
  background-color: red;
  position: absolute;
}

#selector {
  display: inline-block;
  position: absolute;
  pointer-events: none;
  z-index: 9999;
  top: -1000px;
  /*Not showing at start*/
}

#selector .pointers {
  display: inline-block;
  position: absolute;
  z-index: 2;
  width: 10px;
  height: 10px;
  pointer-events: all;
}

#selector .pointers .point {
  width: 10px;
  height: 10px;
  background-color: #fff;
  border: 2px solid rgba(0, 0, 0, 0.9);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

#selector .pointers.pointer1 {
  top: -5px;
  left: -5px;
}

#selector .pointers.pointer2 {
  bottom: -5px;
  left: -5px;
}

#selector .pointers.pointer3 {
  top: -5px;
  right: -5px;
}

#selector .pointers.pointer4 {
  bottom: -5px;
  right: -5px;
}

#selector .pointers.pointer-north {
  top: -5px;
  left: calc(50% - 5px);
}

#selector .pointers.pointer-south {
  bottom: -5px;
  left: calc(50% - 5px);
}

#selector .pointers.pointer-east {
  right: -5px;
  top: calc(50% - 5px);
}

#selector .pointers.pointer-west {
  left: -5px;
  top: calc(50% - 5px);
}

#selector .pointer-rotate {
  border: 2px solid rgba(0, 0, 0, 0.9);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  cursor: rotate;
}

#selector .pointer9 {
  bottom: -70px;
  left: calc(50% - 11px);
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: #fff;
  pointer-events: all;
  position: absolute;
}

#selector .rotate-line {
  border-left: 1px dashed #5f5f5f;
  height: 40px;
  position: absolute;
  top: -40px;
  left: calc(50% - 1px);
  width: 1px;
}

HTML:

<div id="container">
  <div id="rectangle">
  </div>
  <div id="selector">
    <div class="pointers pointer1">
      <div class="point"></div>
    </div>
    <div class="pointers pointer2">
      <div class="point">
      </div>
    </div>
    <div class="pointers pointer3">
      <div class="point">
      </div>
    </div>
    <div class="pointers pointer4">
      <div class="point">
      </div>
    </div>
    <div class="pointers pointer-north">
      <div class="point">
      </div>
    </div>
    <div class="pointers pointer-east">
      <div class="point">

      </div>
    </div>
    <div class="pointers pointer-south">
      <div class="point">
      </div>
    </div>
    <div class="pointers pointer-west">
      <div class="point">
      </div>
    </div>
    <span class="topline lines-resize" />
    <span class="rightline lines-resize" />
    <span class="botline lines-resize" />
    <span class="leftline lines-resize" />
    <div class="pointer-rotate pointer9" />
    <div class="rotate-line" />
  </div>
</div>

用于测试的小提琴:

https://jsfiddle.net/ub70028c/46/

我读过其他人试图做同样的事情但没有结果......

谢谢!

【问题讨论】:

    标签: javascript resize interact.js


    【解决方案1】:

    我检查了resizablerotatable 的代码和类似库,发现了你的问题。

    首先,检查相似库:

    请看我由jquery.freetrans.js创建的fiddle

    如果你检查&lt;div class="shape"&gt;,你可以看到

    transform: matrix(1, 0, 0, 1, 0, 0);
    

    如果你旋转它,transform 改变如下:

    transform: matrix(0.997373, -0.0724379, 0.0724379, 0.997373, 0, 0);
    

    在类似的情况下,your code 使用 transform,起初它没有使用transform,旋转后如下所示:

    transform: rotate(-2.49576deg);
    

    如果您可以在transform 中使用matrix 而不是rotate,您的代码将正常工作。如果你不能改变它,你可以使用类似的库,比如jquery.freetrans.js,它可以与旋转和调整大小一起正常工作。

    【讨论】:

    • 我希望数学能做到这一点……但谢谢。我们接近让它工作......即使同时有多个项目。我们正在与一位数学家一起工作,他正在支持我们使代码工作。他正在处理大量三角函数。
    【解决方案2】:

    https://github.com/taye/interact.js/issues/569

    https://github.com/taye/interact.js/issues/499

    https://github.com/taye/interact.js/issues/394

    恐怕你选择了作者明确表达意图的图书馆

    没有内置方法。正如我在#137 中提到的,我对处理缩放或旋转的元素并不感兴趣

    所以你应该问自己的问题是

    我是想找到一种解决方法来使这个库正常工作还是选择一个不同的库?

    更新 1:2018 年 4 月 28 日

    如果您想在画布而不是普通元素中执行此操作,那么我发现 fabric.js 是一个不错的选择

    【讨论】:

    • 我建议你选择另一个库,即使需要计算数学。因为你不想捡起不会按照你想要的方式去的东西。我会看看是否可以发布有关方程式的更多详细信息
    • 谢谢!我不知道有什么库可以做到这一点,而且 jquery-free-transform 已经很老了......而且数学非常“硬编码”。
    • 另一条评论,Interact.js 对我们来说是最好的,因为它为您提供了所有数据以进行自己的操作... delta、edges 等。
    【解决方案3】:

    五天后我们非常接近完成这项工作......我们需要优化所有数学计算......但是是的,这就是我想要的:

    抱歉,我们还没有准备好代码...我将发布所有带有 cmets 的内容以供其他人使用。

    评论:对于数学家来说,这个任务不是很复杂,因为所有的角度都是矩形(90º)。我将尝试对 Interact.js 进行 PR,甚至向其他库默认实现此功能。希望这项工作对其他开发人员有所帮助;)

    【讨论】:

    • 你能分享一下变换矩阵的数学运算吗?我也卡住了:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多