From 1dde989919d2c272ca7fcaa5c4b2d9ee02c490a0 Mon Sep 17 00:00:00 2001 From: Ram N Date: Mon, 12 Mar 2018 14:47:50 -0700 Subject: [PATCH] Add support for springDamping in SpringInterpolator Reviewed By: mdvacca Differential Revision: D7201334 fbshipit-source-id: 50929b4294188cd5a2a8ffa2080c38c0a9983535 --- .../AbstractLayoutAnimation.java | 28 +++++++++++-------- .../SimpleSpringInterpolator.java | 24 +++++++++++++++- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java index 4fbd6938a9c574..1ad6ccab3946d5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java @@ -2,21 +2,20 @@ package com.facebook.react.uimanager.layoutanimation; -import javax.annotation.Nullable; - -import java.util.Map; - +import android.os.Build; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; +import android.view.animation.BaseInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; - import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.IllegalViewOperationException; +import java.util.Map; +import javax.annotation.Nullable; /** * Class responsible for parsing and converting layout animation data into native {@link Animation} @@ -36,12 +35,11 @@ */ abstract @Nullable Animation createAnimationImpl(View view, int x, int y, int width, int height); - private static final Map INTERPOLATOR = MapBuilder.of( + private static final Map INTERPOLATOR = MapBuilder.of( InterpolatorType.LINEAR, new LinearInterpolator(), InterpolatorType.EASE_IN, new AccelerateInterpolator(), InterpolatorType.EASE_OUT, new DecelerateInterpolator(), - InterpolatorType.EASE_IN_EASE_OUT, new AccelerateDecelerateInterpolator(), - InterpolatorType.SPRING, new SimpleSpringInterpolator()); + InterpolatorType.EASE_IN_EASE_OUT, new AccelerateDecelerateInterpolator()); private @Nullable Interpolator mInterpolator; private int mDelayMs; @@ -64,7 +62,7 @@ public void initializeFromConfig(ReadableMap data, int globalDuration) { if (!data.hasKey("type")) { throw new IllegalArgumentException("Missing interpolation type."); } - mInterpolator = getInterpolator(InterpolatorType.fromString(data.getString("type"))); + mInterpolator = getInterpolator(InterpolatorType.fromString(data.getString("type")), data); if (!isValid()) { throw new IllegalViewOperationException("Invalid layout animation : " + data); @@ -100,8 +98,16 @@ public void initializeFromConfig(ReadableMap data, int globalDuration) { return animation; } - private static Interpolator getInterpolator(InterpolatorType type) { - Interpolator interpolator = INTERPOLATOR.get(type); + private static Interpolator getInterpolator(InterpolatorType type, ReadableMap params) { + Interpolator interpolator = null; + if (type.equals(InterpolatorType.SPRING)) { + interpolator = new SimpleSpringInterpolator(SimpleSpringInterpolator.getSpringDamping(params)); + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + // Conversion from BaseInterpolator to Interpolator is only possible on this Android versions + interpolator = INTERPOLATOR.get(type); + } + } if (interpolator == null) { throw new IllegalArgumentException("Missing interpolator for type : " + type); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java index 9696fe90a1a3ad..7ca2de98a06068 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java @@ -3,6 +3,8 @@ package com.facebook.react.uimanager.layoutanimation; import android.view.animation.Interpolator; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableType; /** * Simple spring interpolator @@ -11,10 +13,30 @@ /* package */ class SimpleSpringInterpolator implements Interpolator { private static final float FACTOR = 0.5f; + public static final String PARAM_SPRING_DAMPING = "springDamping"; + private final float mSpringDamping; + + public static float getSpringDamping(ReadableMap params){ + if (params.getType(PARAM_SPRING_DAMPING).equals(ReadableType.Number)){ + return (float) params.getDouble(PARAM_SPRING_DAMPING); + } else { + return FACTOR; + } + } + + public SimpleSpringInterpolator() { + mSpringDamping = FACTOR; + } + + public SimpleSpringInterpolator(float springDamping){ + mSpringDamping = springDamping; + } @Override public float getInterpolation(float input) { + // Using mSpringDamping in this equation is not really the exact mathematical springDamping, but a good approximation + // We need to replace this equation with the right Factor that accounts for damping and friction return (float) - (1 + Math.pow(2, -10 * input) * Math.sin((input - FACTOR / 4) * Math.PI * 2 / FACTOR)); + (1 + Math.pow(2, -10 * input) * Math.sin((input - mSpringDamping / 4) * Math.PI * 2 / mSpringDamping)); } }