Unify platform behavior of processTransform (#33579)

Summary:
Currently both iOS and Android send over the list of transforms as an array.   But there is an if statement that causes other platforms to get a matrix.  This prevents other platforms from being able to use the fabric ViewProps class and the conversion functions as they exist in core, as those expect the transforms to be an array.

Stop special casing iOS and android. - Which will allow for example Windows to be able to share more fabric code.

## Changelog

[Internal] [Changed] - All platforms should get transform sent to native as an array of transform operations instead of a matrix

Pull Request resolved: https://github.com/facebook/react-native/pull/33579

Test Plan:
Similar change made in react-native-windows.
https://github.com/microsoft/react-native-windows/issues/9797

Reviewed By: NickGerleman

Differential Revision: D38615676

Pulled By: cortinico

fbshipit-source-id: 8861afe6bf34bebb09dd82f7365faf007dd79cbf
This commit is contained in:
Andrew
2022-08-15 06:37:16 -07:00
committed by Facebook GitHub Bot
parent be391844f7
commit ee33385cdd
+1 -108
View File
@@ -10,9 +10,6 @@
'use strict';
const MatrixMath = require('../Utilities/MatrixMath');
const Platform = require('../Utilities/Platform');
const invariant = require('invariant');
const stringifySafe = require('../Utilities/stringifySafe').default;
@@ -31,111 +28,7 @@ function processTransform(
_validateTransforms(transform);
}
// Android & iOS implementations of transform property accept the list of
// transform properties as opposed to a transform Matrix. This is necessary
// to control transform property updates completely on the native thread.
if (Platform.OS === 'android' || Platform.OS === 'ios') {
return transform;
}
const result = MatrixMath.createIdentityMatrix();
transform.forEach(transformation => {
const key = Object.keys(transformation)[0];
const value = transformation[key];
switch (key) {
case 'matrix':
MatrixMath.multiplyInto(result, result, value);
break;
case 'perspective':
_multiplyTransform(result, MatrixMath.reusePerspectiveCommand, [value]);
break;
case 'rotateX':
_multiplyTransform(result, MatrixMath.reuseRotateXCommand, [
_convertToRadians(value),
]);
break;
case 'rotateY':
_multiplyTransform(result, MatrixMath.reuseRotateYCommand, [
_convertToRadians(value),
]);
break;
case 'rotate':
case 'rotateZ':
_multiplyTransform(result, MatrixMath.reuseRotateZCommand, [
_convertToRadians(value),
]);
break;
case 'scale':
_multiplyTransform(result, MatrixMath.reuseScaleCommand, [value]);
break;
case 'scaleX':
_multiplyTransform(result, MatrixMath.reuseScaleXCommand, [value]);
break;
case 'scaleY':
_multiplyTransform(result, MatrixMath.reuseScaleYCommand, [value]);
break;
case 'translate':
_multiplyTransform(result, MatrixMath.reuseTranslate3dCommand, [
value[0],
value[1],
value[2] || 0,
]);
break;
case 'translateX':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [
value,
0,
]);
break;
case 'translateY':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [
0,
value,
]);
break;
case 'skewX':
_multiplyTransform(result, MatrixMath.reuseSkewXCommand, [
_convertToRadians(value),
]);
break;
case 'skewY':
_multiplyTransform(result, MatrixMath.reuseSkewYCommand, [
_convertToRadians(value),
]);
break;
default:
throw new Error('Invalid transform name: ' + key);
}
});
return result;
}
/**
* Performs a destructive operation on a transform matrix.
*/
/* $FlowFixMe[missing-this-annot] The 'this' type annotation(s) required by
* Flow's LTI update could not be added via codemod */
function _multiplyTransform(
result: Array<number>,
matrixMathFunction: Function,
args: Array<number>,
): void {
const matrixToApply = MatrixMath.createIdentityMatrix();
const argsWithIdentity = [matrixToApply].concat(args);
matrixMathFunction.apply(this, argsWithIdentity);
MatrixMath.multiplyInto(result, result, matrixToApply);
}
/**
* Parses a string like '0.5rad' or '60deg' into radians expressed in a float.
* Note that validation on the string is done in `_validateTransform()`.
*/
function _convertToRadians(value: string): number {
const floatValue = parseFloat(value);
return value.indexOf('rad') > -1 ? floatValue : (floatValue * Math.PI) / 180;
return transform;
}
function _validateTransforms(transform: Array<Object>): void {