mhe*_*ers 6 javascript transform matrix react-native
我正在阅读这篇文章,该文章解释了如何使用反应原生进行旋转变换MatrixMath.我试图动画对象的比例,而不是旋转,我希望它使用对象的左上角而不是中心的原点进行缩放.任何人都可以解释如何做到这一点?
旋转矩阵的相关代码位是:
const matrix = transformUtil.rotateX(dx);
transformUtil.origin(matrix, { x: 0, y, z: 0 });
const perspective = this.props.perspective || rootDefaultProps.perspective;
ref.setNativeProps({
style: {
transform: [
{ perspective },
{ matrix },
],
},
});
Run Code Online (Sandbox Code Playgroud)
并且,从transformUtil:
import MatrixMath from 'react-native/Libraries/Utilities/MatrixMath';
function transformOrigin(matrix, origin) {
const { x, y, z } = origin;
const translate = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate3dCommand(translate, x, y, z);
MatrixMath.multiplyInto(matrix, translate, matrix);
const untranslate = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate3dCommand(untranslate, -x, -y, -z);
MatrixMath.multiplyInto(matrix, matrix, untranslate);
}
function rotateX(deg) {
const rad = (Math.PI / 180) * deg;
const cos = Math.cos(rad);
const sin = Math.sitransfn(rad);
return [
1, 0, 0, 0,
0, cos, -sin, 0,
0, sin, cos, 0,
0, 0, 0, 1,
];
}
export default {
rotateX,
origin: transformOrigin,
};
Run Code Online (Sandbox Code Playgroud)
在深入研究所描述问题的解决方案之前,我强烈建议任何阅读本文的人学习(或温习)矩阵乘法。有一些很棒的资源可以做到这一点,但我个人最喜欢的是可汗学院。
如果您只想阅读代码,这里是Snack 中的工作解决方案: https: //snack.expo.io/BJnDImQlr
分解:
我们需要做的第一件事是设置要缩放的对象的变换原点。transformOrigin我们将使用OP 在他们的问题中包含的文章中的部分函数。然而,我们只需要修改原点一次,因为不需要将其重置回顶部(文章中的特定动画要求它返回顶部)。
function transformOrigin(matrix, origin) {
const { x, y, z } = origin;
const translate = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate3dCommand(translate, x, y, z);
MatrixMath.multiplyInto(matrix, translate, matrix);
}
Run Code Online (Sandbox Code Playgroud)
MatrixMath.createIdentityMatrix我们可以使用矩阵乘法缩放由适当矩阵(即 )表示的任何对象。如果我们将下面描述的矩阵乘以目标对象矩阵,我们最终将得到缩放为 的相同对象矩阵x。
function scale(x) {
return [
x, 0, 0, 0,
0, x, 0, 0,
0, 0, x, 0,
0, 0, 0, 1
];
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要将所有内容放在一起。
ref及其属性。xAxis: 0, yAxis: 0)。MatrixMath.multiplyInto通过矩阵乘法处理前面的所有步骤。ref通过将变换应用于目标对象setNativeProps。
function transformScale(ref, scaleBy, width, height) {
const matrix = MatrixMath.createIdentityMatrix();
const toScale = scale(scaleBy);
transformOrigin(matrix, {
x: (width * scaleBy - width) / 2,
y: (height * scaleBy - height) / 2,
z: 0
});
MatrixMath.multiplyInto(matrix, matrix, toScale);
ref.setNativeProps({
style: { transform: [{ matrix }] }
});
}
Run Code Online (Sandbox Code Playgroud)
现在,我们将上述所有方法添加到 React 组件中。如果要增大或减小对象的比例,请更改 中的第二个参数transformScale(this._target, 3, width, height)。您甚至可以设置为scaleBy动态值并用它制作动画。
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
width: 0,
height: 0
};
}
handleBaseLayout = (e) => {
const { width, height } = e.nativeEvent.layout;
this.setState({ width, height }, () => {
transformScale(this._target, 3, width, height);
});
};
render() {
return (
<View style={styles.container}>
<View
style={styles.target}
ref={c => (this._target = c)}
onLayout={this.handleBaseLayout}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
target: {
width: 100,
height: 100,
backgroundColor: 'blue',
},
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
913 次 |
| 最近记录: |