Add support for springDamping in SpringInterpolator

Reviewed By: mdvacca

Differential Revision: D7201334

fbshipit-source-id: 50929b4294188cd5a2a8ffa2080c38c0a9983535
This commit is contained in:
Ram N 2018-03-12 14:47:50 -07:00 committed by Facebook Github Bot
parent 9c8c597000
commit 1dde989919
2 changed files with 40 additions and 12 deletions

View File

@ -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 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
*/
abstract @Nullable Animation createAnimationImpl(View view, int x, int y, int width, int height);
private static final Map<InterpolatorType, Interpolator> INTERPOLATOR = MapBuilder.of(
private static final Map<InterpolatorType, BaseInterpolator> 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 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
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 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
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);
}

View File

@ -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 @@ import android.view.animation.Interpolator;
/* 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));
}
}