Add perspective transform support on Android

Summary:
Rebased #6926 against master.

Fixes #2915
Closes https://github.com/facebook/react-native/pull/11713

Differential Revision: D4513111

fbshipit-source-id: 9fb653c4bfd64eda12a605f6cabb0159b2af8f73
This commit is contained in:
Satyajit Sahoo 2017-02-04 11:05:37 -08:00 committed by Facebook Github Bot
parent a3457486e3
commit a06ced4b16
2 changed files with 21 additions and 3 deletions

View File

@ -211,7 +211,7 @@ exports.title = 'Transforms';
exports.description = 'View transforms';
exports.examples = [
{
title: 'Perspective',
title: 'Perspective, Rotate, Animation',
description: 'perspective: 850, rotateX: Animated.timing(0 -> 360)',
render(): React.Element<any> { return <Flip />; }
},

View File

@ -5,8 +5,6 @@ package com.facebook.react.uimanager;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.annotations.ReactProp;
@ -35,6 +33,9 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
private static final String PROP_TRANSLATE_X = "translateX";
private static final String PROP_TRANSLATE_Y = "translateY";
private static final int PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX = 2;
private static final float CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER = 5;
/**
* Used to locate views in end-to-end (UI) tests.
*/
@ -165,6 +166,22 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
view.setRotationY((float) sMatrixDecompositionContext.rotationDegrees[1]);
view.setScaleX((float) sMatrixDecompositionContext.scale[0]);
view.setScaleY((float) sMatrixDecompositionContext.scale[1]);
double[] perspectiveArray = sMatrixDecompositionContext.perspective;
if (perspectiveArray.length > PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) {
float invertedCameraDistance = (float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
if (invertedCameraDistance < 0) {
float cameraDistance = -1 / invertedCameraDistance;
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 resetTransformProperty(View view) {
@ -175,5 +192,6 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
view.setRotationY(0);
view.setScaleX(1);
view.setScaleY(1);
view.setCameraDistance(0);
}
}