Skip to content

Commit

Permalink
Add backface-visibility support on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
charpeni committed Aug 24, 2018
1 parent e2f2e41 commit ab03bf1
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ public class MatrixMathHelper {
private static final double EPSILON = .00001d;

public static class MatrixDecompositionContext {
double[] perspective = new double[4];
double[] scale = new double[3];
double[] skew = new double[3];
double[] translation = new double[3];
double[] rotationDegrees = new double[3];
public double[] perspective = new double[4];
public double[] scale = new double[3];
public double[] skew = new double[3];
public double[] translation = new double[3];
public double[] rotationDegrees = new double[3];
}

private static boolean isZero(double d) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import android.view.animation.Animation;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.modules.i18nmanager.I18nUtil;
import com.facebook.react.touch.OnInterceptTouchEventListener;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.touch.ReactInterceptingViewGroup;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.touch.OnInterceptTouchEventListener;
import com.facebook.react.uimanager.MatrixMathHelper;
import com.facebook.react.uimanager.MeasureSpecAssertions;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ReactClippingViewGroup;
Expand All @@ -36,6 +39,7 @@
import com.facebook.react.uimanager.ReactZIndexedViewGroup;
import com.facebook.react.uimanager.RootView;
import com.facebook.react.uimanager.RootViewUtil;
import com.facebook.react.uimanager.TransformHelper;
import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.yoga.YogaConstants;
Expand All @@ -56,6 +60,7 @@ public class ReactViewGroup extends ViewGroup implements
private static final LayoutParams sDefaultLayoutParam = new ViewGroup.LayoutParams(0, 0);
/* should only be used in {@link #updateClippingToRect} */
private static final Rect sHelperRect = new Rect();
private static double[] sTransformDecompositionArray = new double[16];

/**
* This listener will be set for child views when removeClippedSubview property is enabled. When
Expand Down Expand Up @@ -113,6 +118,10 @@ public void onLayoutChange(
private final ViewGroupDrawingOrderHelper mDrawingOrderHelper;
private @Nullable Path mPath;
private int mLayoutDirection;
private float mBackfaceOpacity = 1.f;
private String mBackfaceVisibility = "visible";
private MatrixMathHelper.MatrixDecompositionContext sMatrixDecompositionContext =
new MatrixMathHelper.MatrixDecompositionContext();

public ReactViewGroup(Context context) {
super(context);
Expand Down Expand Up @@ -865,4 +874,45 @@ private void dispatchOverflowDraw(Canvas canvas) {
}
}
}

public void setOpacityIfPossible(float opacity) {
mBackfaceOpacity = opacity;
setBackfaceVisibilityDependantOpacity();
}

public void setBackfaceVisibility(String backfaceVisibility) {
mBackfaceVisibility = backfaceVisibility;
setBackfaceVisibilityDependantOpacity();
}

public void decomposeMatrix(ReadableArray matrix) {
if (matrix != null) {
TransformHelper.processTransform(matrix, sTransformDecompositionArray);
MatrixMathHelper.decomposeMatrix(sTransformDecompositionArray, sMatrixDecompositionContext);
setBackfaceVisibilityDependantOpacity();
}
}

private void setBackfaceVisibilityDependantOpacity() {
boolean isBackfaceVisible = mBackfaceVisibility.equals("visible");
boolean isRotationInformationAvailable = sMatrixDecompositionContext != null;

if (isBackfaceVisible || !isRotationInformationAvailable) {
setAlpha(mBackfaceOpacity);
return;
}

float rotationX = (float) sMatrixDecompositionContext.rotationDegrees[0];
float rotationY = (float) sMatrixDecompositionContext.rotationDegrees[1];

boolean isFrontfaceVisible = (rotationX >= -90.f && rotationX < 90.f) &&
(rotationY >= -90.f && rotationY < 90.f);

if (isFrontfaceVisible) {
setAlpha(mBackfaceOpacity);
return;
}

setAlpha(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,22 @@ public void setOverflow(ReactViewGroup view, String 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.decomposeMatrix(matrix);
}

@Override
public String getName() {
return REACT_CLASS;
Expand Down

0 comments on commit ab03bf1

Please sign in to comment.