Skip to content

Commit

Permalink
Add support for springDamping in SpringInterpolator
Browse files Browse the repository at this point in the history
Reviewed By: mdvacca

Differential Revision: D7201334

fbshipit-source-id: 50929b4294188cd5a2a8ffa2080c38c0a9983535
  • Loading branch information
axe-fb authored and facebook-github-bot committed Mar 12, 2018
1 parent 9c8c597 commit 1dde989
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -36,12 +35,11 @@
*/
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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
}
}

0 comments on commit 1dde989

Please sign in to comment.