14

I want to apply a translate animation on an Android view (button) using a custom interpolator where the easing function is:

public static float easeOut(float t,float b , float c, float d) {
    if ((t/=d) < (1/2.75f)) {
       return c*(7.5625f*t*t) + b;
    } else if (t < (2/2.75f)) {
       return c*(7.5625f*(t-=(1.5f/2.75f))*t + .75f) + b;
    } else if (t < (2.5/2.75)) {
       return c*(7.5625f*(t-=(2.25f/2.75f))*t + .9375f) + b;
    } else {
       return c*(7.5625f*(t-=(2.625f/2.75f))*t + .984375f) + b;
    }
}

I have an example that uses the custom interpolator like this:

The interpolator is:

public class HesitateInterpolator implements Interpolator {
    public HesitateInterpolator() {
    }

    public float getInterpolation(float t) {
        float x = 2.0f * t - 1.0f;
        return 0.5f * (x * x * x + 1.0f);
    }
}

and is used like this:

ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
anim.setInterpolator(new HesitateInterpolator());

My question is: What are these values b, c, d for?

Rodia
  • 1,407
  • 8
  • 22
  • 29
Adham
  • 63,550
  • 98
  • 229
  • 344

5 Answers5

24

FYI: for people who just want an ease interpolator you can just use myAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

Francois Dermu
  • 4,437
  • 2
  • 22
  • 14
15

I made a library which can solve this problem. AndroidEasingFunctions

daimajia
  • 967
  • 12
  • 15
  • 2
    Great library! I do feel it's necessary to note that you should not import Android's ObjectAnimator and AnimatorSet, but com.nineoldandroids's, so it's also necessary to compile 'com.nineoldandroids:library:2.4.0' – marienke Nov 26 '14 at 15:56
  • 2
    Thanks for the library though! :) Just add some documentation on the usage or what to look out for. – marienke Nov 27 '14 at 06:55
12

1,2,3 go

  1. Create a custom cubic bezier curve using this awesome site. And get the control points for the curve. Between 0,0 and 1,1
  2. Interpolator customInterpolator = PathInterpolatorCompat.create(cpX1,cpX2,cpY1,cpY2)
  3. Add this customInterpolator to any of your animation.

Added a gist. Some more here.

amalBit
  • 12,041
  • 6
  • 77
  • 94
11

According to Robert Penner's Easing Functions, as stated here:

t: current time, b: begInnIng value, c: change In value, d: duration

If you want to implement your custom Interpolator, you have to make something like this:

(this would be the implementation for the easeInOutQuint)

public class MVAccelerateDecelerateInterpolator implements Interpolator {

    // easeInOutQuint
    public float getInterpolation(float t) {
        float x;
        if (t<0.5f)
        { 
            x = t*2.0f;
            return 0.5f*x*x*x*x*x;
        }
        x = (t-0.5f)*2-1;
        return 0.5f*x*x*x*x*x+1;
    }
}

Edit: to implement the easing function you need some math knowledge, considering that the getInterpolation method gets only the t parameter, from 0.0 to 1.0.

So basically you need to develop a y(t) function, with t from 0 to 1, and with y values from 0 to 1, as shown below:

enter image description here

What you change is the curve to get from 0 to 1 (in the image the green line is the linear one, for example). You need to 'normalize' the easing functions to remain in the (0, 1) x (0, 1) square, as you can see in my easeInOutQuint implementation.

ʞᴉɯ
  • 5,376
  • 7
  • 52
  • 89
  • Thank you for your great answer, but how did you get this functions you mentioned in your answer?.. How to convert the functions that Robert wrote to java functions in factor of t only ? – Adham Apr 12 '14 at 18:07
  • Thank you very much for you clarification, can you provide me with reference to learn how to normalize function to function from 0-1 function ? – Adham Apr 25 '14 at 17:54
  • Sorry but is matter of math knownledge... i've made it by me. You can use a visual plot tool to simplify the job, such as http://rechneronline.de/function-graphs/ – ʞᴉɯ Apr 25 '14 at 18:15
  • Sorry for many questions I ask :(, If I have equation like this: easeInOutQuad: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; }, .. How can I make the equation only have only one variable,, y = f(x) .. what do you use for the constants – Adham Apr 25 '14 at 18:26
  • The functions for easeInOutQuad are: (x*2)^2/2 for t<0.5 -((x-1)^2)*2+1 for t>0.5 – ʞᴉɯ Apr 26 '14 at 15:03
0

Here is another solution, made possible by a recent addition to android's support library: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce

and an example in use:

public static void expand(final View v) {
    v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    final int targetHeight = v.getMeasuredHeight();

    if ( v.getHeight() != targetHeight ) {
        // Older versions of android (pre API 21) cancel animations for views with a height of 0 so use 1 instead.
        v.getLayoutParams().height = 1;
        v.setVisibility(View.VISIBLE);


        Animation a = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                v.getLayoutParams().height = interpolatedTime == 1
                        ? ViewGroup.LayoutParams.WRAP_CONTENT
                        : (int) (targetHeight * interpolatedTime);
                v.requestLayout();
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        a.setInterpolator(EasingsConstants.easeInOutQuart);
        a.setDuration(computeDurationFromHeight(v));
        v.startAnimation(a);
    } else {
        Log.d("AnimationUtil", "expand Already expanded ");
    }
}

/**
 * 1dp/ms * multiplier
 */
private static int computeDurationFromHeight(View v) {
    return (int) (v.getMeasuredHeight() / v.getContext().getResources().getDisplayMetrics().density) * DURATION_MULTIPLIER;
}
Erik B
  • 2,810
  • 1
  • 34
  • 38
  • gist link not working.. Is EasingsConstants a custom class? – Rik van Velzen Jul 12 '17 at 09:06
  • 1
    @RikvanVelzen sorry about that, the link was removed from another answer so I deleted the gist. It is a custom class with a bunch of constants defining values from easings.net like so: public static final Interpolator easeInOutQuad = PathInterpolatorCompat.create(0.455f, 0.03f, 0.515f, 0.955f); – Erik B Jul 12 '17 at 19:19