Skip to content

Commit e2eeaaf

Browse files
committed
Use animation matrix after android Q
1 parent 04ad34d commit e2eeaaf

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.facebook.react.uimanager;
99

1010
import android.graphics.Color;
11+
import android.graphics.Matrix;
1112
import android.os.Build;
1213
import android.text.TextUtils;
1314
import android.view.View;
@@ -440,6 +441,14 @@ public void setAccessibilityLiveRegion(@NonNull T view, @Nullable String liveReg
440441
}
441442

442443
private static void setTransformProperty(@NonNull View view, ReadableArray transforms) {
444+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
445+
Matrix matrix = new Matrix();
446+
if (TransformHelper.tryProcessTransformBySkiaMatrix(transforms, matrix, view.getWidth(),
447+
view.getHeight())) {
448+
view.setAnimationMatrix(matrix);
449+
return;
450+
}
451+
}
443452
sMatrixDecompositionContext.reset();
444453
TransformHelper.processTransform(transforms, sTransformDecompositionArray);
445454
MatrixMathHelper.decomposeMatrix(sTransformDecompositionArray, sMatrixDecompositionContext);

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/MatrixMathHelper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ public static double degreesToRadians(double degrees) {
468468
return degrees * Math.PI / 180;
469469
}
470470

471+
public static double radiansToDegrees(double radians) {
472+
return radians * 180 / Math.PI;
473+
}
474+
471475
public static void resetIdentityMatrix(double[] matrix) {
472476
matrix[1] =
473477
matrix[2] =

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/TransformHelper.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package com.facebook.react.uimanager;
99

10+
import android.graphics.Matrix;
11+
1012
import com.facebook.common.logging.FLog;
1113
import com.facebook.react.bridge.ReadableArray;
1214
import com.facebook.react.bridge.ReadableMap;
@@ -107,4 +109,87 @@ public static void processTransform(ReadableArray transforms, double[] result) {
107109
MatrixMathHelper.multiplyInto(result, result, helperMatrix);
108110
}
109111
}
112+
113+
114+
private static double convertToDegrees(ReadableMap transformMap, String key) {
115+
double value;
116+
boolean inRadians = true;
117+
if (transformMap.getType(key) == ReadableType.String) {
118+
String stringValue = transformMap.getString(key);
119+
if (stringValue.endsWith("deg")) {
120+
inRadians = false;
121+
}
122+
if (stringValue.endsWith("rad") || stringValue.endsWith("deg")) {
123+
stringValue = stringValue.substring(0, stringValue.length() - 3);
124+
}
125+
value = Float.parseFloat(stringValue);
126+
} else {
127+
value = transformMap.getDouble(key);
128+
}
129+
return inRadians ? MatrixMathHelper.radiansToDegrees(value) : value;
130+
}
131+
132+
133+
public static boolean tryProcessTransformBySkiaMatrix(ReadableArray transforms, Matrix matrix,
134+
int viewWidth, int viewHeight) {
135+
assert matrix != null;
136+
matrix.reset();
137+
// center of view.
138+
int originX = viewWidth / 2, originY = viewHeight / 2;
139+
140+
for (int transformIdx = 0, size = transforms.size(); transformIdx < size; transformIdx++) {
141+
ReadableMap transform = transforms.getMap(transformIdx);
142+
String transformType = transform.keySetIterator().nextKey();
143+
144+
if ("translate".equals(transformType)) {
145+
ReadableArray value = transform.getArray(transformType);
146+
double x = value.getDouble(0);
147+
double y = value.getDouble(1);
148+
double z = value.size() > 2 ? value.getDouble(2) : 0d;
149+
// Not support translate in z axis.
150+
if (z != 0) {
151+
return false;
152+
}
153+
originX += x;
154+
originY += y;
155+
matrix.postTranslate(PixelUtil.toPixelFromDIP((float) x), PixelUtil.toPixelFromDIP((float) y));
156+
} else if ("translateX".equals(transformType)) {
157+
double x = transform.getDouble(transformType);
158+
originX += x;
159+
matrix.postTranslate(PixelUtil.toPixelFromDIP(x), 0);
160+
} else if ("translateY".equals(transformType)) {
161+
double y = transform.getDouble(transformType);
162+
originY += y;
163+
matrix.postTranslate(0, PixelUtil.toPixelFromDIP(y));
164+
}
165+
}
166+
167+
for (int transformIdx = 0, size = transforms.size(); transformIdx < size; transformIdx++) {
168+
ReadableMap transform = transforms.getMap(transformIdx);
169+
String transformType = transform.keySetIterator().nextKey();
170+
171+
if ("rotate".equals(transformType) || "rotateZ".equals(transformType)) {
172+
matrix.postRotate((float) convertToDegrees(transform, transformType), originX, originY);
173+
} else if ("scale".equals(transformType)) {
174+
float scale = (float)transform.getDouble(transformType);
175+
matrix.postScale(scale, scale, originX, originY);
176+
} else if ("scaleX".equals(transformType)) {
177+
matrix.postScale((float)transform.getDouble(transformType), 1, originX, originY);
178+
} else if ("scaleY".equals(transformType)) {
179+
matrix.postScale(1, (float)transform.getDouble(transformType), originX, originY);
180+
} else if ("translate".equals(transformType) || "translateX".equals(transformType)
181+
|| "translateY".equals(transformType)) {
182+
// translate has been processed.
183+
} else if ("skewX".equals(transformType)) {
184+
matrix.postSkew((float) convertToRadians(transform, transformType), 0);
185+
} else if ("skewY".equals(transformType)) {
186+
matrix.postSkew(0, (float) convertToRadians(transform, transformType));
187+
} else {
188+
// matrix, perspective rotateX rotateY
189+
return false;
190+
}
191+
}
192+
return true;
193+
}
194+
110195
}

0 commit comments

Comments
 (0)