在React Native中创建矩阵变换系统?

时间:2018-04-24 09:03:02

标签: javascript reactjs react-native math geometry

我刚刚在React Native中构建了一个相对复杂的图像编辑UI。

该体验旨在与Instagram非常相似,并具有双指缩放,平移和旋转功能。

转换存储为数据,例如:

transformation: {
  bottomBoundary: 1989,
  leftBoundary: 410,
  rightBoundary: 1634,
  topBoundary: 765,
  rotation: 0,
},

其中topBoundarybottomBoundary都是偏离图片顶部的偏移量,leftBoundaryrightBoundary都是偏离图片左侧的偏移量。

旋转时,因为React Native使用对象的中心作为变换原点,所以当处于90°或270°方向时,图像需要偏移,这样它们仍然可以“粘”到顶部/左上角并且可以被抵消:

calculateRotationOffset.js

export default function (width, height) {
  const transform = [
    { rotate: `${this.rotation}deg` },
  ]

  /*
    RN rotates around centre point, so we need to
    manually offset the rotation to stick the image
    to the top left corner so that our offsets will
    work.
  */
  if (this.rotation === 90) {
    transform.push(
      { translateX: -((width - height) / 2) },
      { translateY: -((width - height) / 2) },
    )
  } else if (this.rotation === 270) {
    transform.push(
      { translateX: ((width - height) / 2) },
      { translateY: ((width - height) / 2) },
    )
  }
  return transform
}

关于我的旋转和缩放实现的某些内容无法协同工作。

Here is the complete snack example.

重现错误:

  1. 旋转图像一次
  2. 捏放大或缩小
  3. 再次旋转图像
  4. 现在图片将被翻转并错误地偏移。

    此处依次发生至少三次转换以重现错误,因此我无法追踪问题。

    如果有必要,这个问题一定会得到解决,我也可以提供金钱奖励。谢谢!

    更新:经过一些建议,似乎解决这个问题的最佳方法是通过矩阵变换,然后以某种方式将此矩阵转换回RN可以在屏幕上表示的样式。矩阵变换需要支持平移,旋转和缩放。

1 个答案:

答案 0 :(得分:-1)

我用分解的转换矩阵(旋转,缩放,平移)替换bottomBoundary等,并在UI中使用多点触控。在图像上滑动单个手指时,可以更新矩阵的平移分量,并用2个手指对其进行变换,使图像看起来粘在手指上。如果要将旋转约束为90度增量,则可以在用户放开时将其捕捉。这使您可以在图像中自由直观地移动,而无需当前的旋转按钮。

始终以分解形式存储矩阵可避免必须对其进行分解或标准化,以避免累积数值不准确(偏斜和改变纵横比)。

创建新的DecomposedMatrix类有助于构建代码。关键是处理它大致如下:

scaleBy(scale) {
    this.scale *= scale;
    this.x *= scale;
    this.y *= scale;
}