Add backface-visibility support on Android (#15970)
Summary: `backfaceVisibility` was only available on iOS and 3D transformations were lacking on Android. Backface Visibility is computed from ~the decomposed matrix of transform prop~ the view with their rotation degree values. ~`MatrixDecompositionContext` properties have been made public so we can access to decomposed matrix values from outside (`ReactViewGroup`).~ I'm not sure if this is the best implementation, so if it's not let's discuss it. cc janicduplessis foghina Tested in https://github.com/charpeni/react-native-backface-visibility. | Before | Now | | - | - | | <img src="https://user-images.githubusercontent.com/7189823/30123717-e5361598-9300-11e7-8e2e-a87a7a8d896a.gif" width="260" /> | <img src="https://user-images.githubusercontent.com/7189823/30514997-4d203572-9aee-11e7-8542-bfde41678eb6.gif" width="244" /> | | iOS | Android | | - | - | | <img src="https://user-images.githubusercontent.com/7189823/36995899-609513b4-2083-11e8-9834-ee44c1a292e1.gif" width="300" /> | <img src="https://user-images.githubusercontent.com/7189823/36995978-9ed3b158-2083-11e8-841e-b9e3357d2509.gif" width="240" /> | [ANDROID] [FEATURE] [ReactViewGroup] - Add backface-visibility support on Android Pull Request resolved: https://github.com/facebook/react-native/pull/15970 Differential Revision: D9411130 Pulled By: hramos fbshipit-source-id: 62f646a4de37d83922286cb98893a95b55fa889e
This commit is contained in:
parent
2f79960a69
commit
0cce0a62c1
Binary file not shown.
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 200 KiB |
Binary file not shown.
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 200 KiB |
Binary file not shown.
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 200 KiB |
|
@ -311,4 +311,72 @@ exports.examples = [
|
||||||
return <ZIndexExample />;
|
return <ZIndexExample />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'BackfaceVisibility',
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Text style={{paddingBottom: 10}}>
|
||||||
|
View #1, front is visible, back is hidden.
|
||||||
|
</Text>
|
||||||
|
<View style={{justifyContent: 'center', alignItems: 'center'}}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 200,
|
||||||
|
width: 200,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
}}>
|
||||||
|
<Text>Front</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 200,
|
||||||
|
width: 200,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
transform: [{rotateY: '180deg'}],
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
}}>
|
||||||
|
<Text>Back (You should not see this)</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={{paddingVertical: 10}}>
|
||||||
|
View #2, front is hidden, back is visible.
|
||||||
|
</Text>
|
||||||
|
<View style={{justifyContent: 'center', alignItems: 'center'}}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 200,
|
||||||
|
width: 200,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
}}>
|
||||||
|
<Text>Front (You should not see this)</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 200,
|
||||||
|
width: 200,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
}}>
|
||||||
|
<Text>Back</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -110,6 +110,8 @@ public class ReactViewGroup extends ViewGroup implements
|
||||||
private final ViewGroupDrawingOrderHelper mDrawingOrderHelper;
|
private final ViewGroupDrawingOrderHelper mDrawingOrderHelper;
|
||||||
private @Nullable Path mPath;
|
private @Nullable Path mPath;
|
||||||
private int mLayoutDirection;
|
private int mLayoutDirection;
|
||||||
|
private float mBackfaceOpacity = 1.f;
|
||||||
|
private String mBackfaceVisibility = "visible";
|
||||||
|
|
||||||
public ReactViewGroup(Context context) {
|
public ReactViewGroup(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -836,4 +838,36 @@ public class ReactViewGroup extends ViewGroup implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOpacityIfPossible(float opacity) {
|
||||||
|
mBackfaceOpacity = opacity;
|
||||||
|
setBackfaceVisibilityDependantOpacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackfaceVisibility(String backfaceVisibility) {
|
||||||
|
mBackfaceVisibility = backfaceVisibility;
|
||||||
|
setBackfaceVisibilityDependantOpacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackfaceVisibilityDependantOpacity() {
|
||||||
|
boolean isBackfaceVisible = mBackfaceVisibility.equals("visible");
|
||||||
|
|
||||||
|
if (isBackfaceVisible) {
|
||||||
|
setAlpha(mBackfaceOpacity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rotationX = getRotationX();
|
||||||
|
float rotationY = getRotationY();
|
||||||
|
|
||||||
|
boolean isFrontfaceVisible = (rotationX >= -90.f && rotationX < 90.f) &&
|
||||||
|
(rotationY >= -90.f && rotationY < 90.f);
|
||||||
|
|
||||||
|
if (isFrontfaceVisible) {
|
||||||
|
setAlpha(mBackfaceOpacity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAlpha(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,22 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
|
||||||
view.setOverflow(overflow);
|
view.setOverflow(overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "backfaceVisibility")
|
||||||
|
public void setBackfaceVisibility(ReactViewGroup view, String backfaceVisibility) {
|
||||||
|
view.setBackfaceVisibility(backfaceVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOpacity(ReactViewGroup view, float opacity) {
|
||||||
|
view.setOpacityIfPossible(opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransform(ReactViewGroup view, ReadableArray matrix) {
|
||||||
|
super.setTransform(view, matrix);
|
||||||
|
view.setBackfaceVisibilityDependantOpacity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return REACT_CLASS;
|
return REACT_CLASS;
|
||||||
|
|
Loading…
Reference in New Issue