Android support for perspective transform

Summary:- Motivation: ["Perspective" Transform](https://facebook.github.io/react-native/docs/transforms.html#proptypes) was so far supported only on iOS
- Closes #2915
- Test Plan: I built a [react-native-flip-view](https://github.com/DispatcherInc/react-native-flip-view) and ensured that the same perspective transform results in the same camera perspective on both iOS and Android:

![image](https://cloud.githubusercontent.com/assets/7293984/13342624/6556cfe0-dbf8-11e5-8fb2-05554a5081b7.png)

![image](https://cloud.githubusercontent.com/assets/7293984/13342677/daf90560-dbf8-11e5-9941-2ae0f9f9d99b.png)
Closes https://github.com/facebook/react-native/pull/6159

Differential Revision: D3053532

Pulled By: mkonicek

fb-gh-sync-id: a39a9fbafe0fc7c648fdafc2eb69f651fe58d9fb
shipit-source-id: a39a9fbafe0fc7c648fdafc2eb69f651fe58d9fb
This commit is contained in:
Kevin Stumpf 2016-03-15 11:51:31 -07:00 committed by Facebook Github Bot 8
parent cc2068e201
commit 3e760f48c5
1 changed files with 20 additions and 1 deletions

View File

@ -6,8 +6,10 @@ import android.graphics.Color;
import android.os.Build;
import android.view.View;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.DisplayMetricsHolder;
/**
* Base class that should be suitable for the majority of subclasses of {@link ViewManager}.
@ -25,6 +27,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
private static final String PROP_DECOMPOSED_MATRIX_SCALE_Y = "scaleY";
private static final String PROP_DECOMPOSED_MATRIX_TRANSLATE_X = "translateX";
private static final String PROP_DECOMPOSED_MATRIX_TRANSLATE_Y = "translateY";
private static final String PROP_DECOMPOSED_MATRIX_PERSPECTIVE = "perspective";
private static final String PROP_OPACITY = "opacity";
private static final String PROP_ELEVATION = "elevation";
private static final String PROP_RENDER_TO_HARDWARE_TEXTURE = "renderToHardwareTextureAndroid";
@ -32,6 +35,8 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
private static final String PROP_ACCESSIBILITY_COMPONENT_TYPE = "accessibilityComponentType";
private static final String PROP_ACCESSIBILITY_LIVE_REGION = "accessibilityLiveRegion";
private static final String PROP_IMPORTANT_FOR_ACCESSIBILITY = "importantForAccessibility";
private static final int PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX = 2;
private static final float CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER = 5;
// DEPRECATED
private static final String PROP_ROTATION = "rotation";
@ -164,6 +169,20 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
(float) matrix.getDouble(PROP_DECOMPOSED_MATRIX_SCALE_X));
view.setScaleY(
(float) matrix.getDouble(PROP_DECOMPOSED_MATRIX_SCALE_Y));
if (matrix.hasKey(PROP_DECOMPOSED_MATRIX_PERSPECTIVE)) {
ReadableArray perspectiveArray = matrix.getArray(PROP_DECOMPOSED_MATRIX_PERSPECTIVE);
if (perspectiveArray.size() > PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) {
float cameraDistance = (float)(-1 / perspectiveArray.getDouble(PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX));
float scale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
// The following converts the matrix's perspective to a camera distance
// such that the camera perspective looks the same on Android and iOS
float normalizedCameraDistance = scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER;
view.setCameraDistance(normalizedCameraDistance);
}
}
}
private static void resetTransformMatrix(View view) {
@ -175,4 +194,4 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
view.setScaleX(1);
view.setScaleY(1);
}
}
}