我刚刚在React Native中构建了一个相对复杂的图像编辑UI。
该体验旨在与Instagram非常相似,并具有双指缩放,平移和旋转功能。
转换存储为数据,例如:
transformation: {
bottomBoundary: 1989,
leftBoundary: 410,
rightBoundary: 1634,
topBoundary: 765,
rotation: 0,
},
其中topBoundary
和bottomBoundary
都是偏离图片顶部的偏移量,leftBoundary
和rightBoundary
都是偏离图片左侧的偏移量。
旋转时,因为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.
重现错误:
现在图片将被翻转并错误地偏移。
此处依次发生至少三次转换以重现错误,因此我无法追踪问题。
如果有必要,这个问题一定会得到解决,我也可以提供金钱奖励。谢谢!
更新:经过一些建议,似乎解决这个问题的最佳方法是通过矩阵变换,然后以某种方式将此矩阵转换回RN可以在屏幕上表示的样式。矩阵变换需要支持平移,旋转和缩放。
答案 0 :(得分:-1)
我用分解的转换矩阵(旋转,缩放,平移)替换bottomBoundary
等,并在UI中使用多点触控。在图像上滑动单个手指时,可以更新矩阵的平移分量,并用2个手指对其进行变换,使图像看起来粘在手指上。如果要将旋转约束为90度增量,则可以在用户放开时将其捕捉。这使您可以在图像中自由直观地移动,而无需当前的旋转按钮。
始终以分解形式存储矩阵可避免必须对其进行分解或标准化,以避免累积数值不准确(偏斜和改变纵横比)。
创建新的DecomposedMatrix
类有助于构建代码。关键是处理它大致如下:
scaleBy(scale) {
this.scale *= scale;
this.x *= scale;
this.y *= scale;
}