Reputation: 2862
I am using the below code to do a transform animation:
transform: [
// scaleX, scaleY, scale, theres plenty more options you can find online for this.
{ scaleY: this.state.ViewScale } // this would be the result of the animation code below and is just a number.
]}}>
Currently, the transform-origin
(<- not actually available in react native) is the center. For the animation, the component scales from the center, so it looks like it is "expanding" from the center. I want it to "expand" from the top (i.e. make the transform origin the top of the component...I think).
I found a method that simulates the transform-origin
css:
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);
}
But I am not sure what matrices to use to affect the component the way I want. I have some understanding of transformation matrices, but only for translating and rotating - I am not sure how to affect the origin of a scale
transform.
For anyone looking to do some digging, thanks: https://en.wikipedia.org/wiki/Transformation_matrix
Upvotes: 4
Views: 3767
Reputation: 477
You need 3 matrix transformations. 1) Translate view center to the desired origin point, 2) Apply scaling, and 3) Apply negative translation.
const matrix = MatrixMath.createIdentityMatrix();
// First translation, move view center to top left corner
const translate = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate3dCommand(translate, -viewWidth / 2, -viewHeight / 2, 0);
MatrixMath.multiplyInto(matrix, matrix, translate);
// Scale, center point and the top left corner are now overlapping so view will expand or shrink from the top left corner
const scale = MatrixMath.createIdentityMatrix();
MatrixMath.reuseScale3dCommand(scale, this.state.ScaleView, this.state.ScaleView, 1);
MatrixMath.multiplyInto(matrix, matrix, scale);
// Move your view's top left corner to it's original position
const untranslate = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate3dCommand(untranslate, viewWidth / 2, viewHeight / 2, 0);
MatrixMath.multiplyInto(matrix, matrix, untranslate);
// You need to set transform matrix somewhere in your JSX like this:
// <View style={{ transform: [ { matrix } ] }} />
// Or, you can call ref.setNativeProps().
I think this way you have to do scaling using matrix, so no need to use specific transform functions like scale/scaleX/scaleY.
You can also manually calculate translate values and use transform's translateX
/translateY
functions to achieve the same effect.
Upvotes: 1