A function for non-linear animation steps (large in the middle, small at the ends)

255 Views Asked by At

In a word game for Android I animate movement of letter tiles (for example when user selects "shuffle tiles" or "return tiles from game board" in menu) in a linear way (they have constant velocities) by the algorithm explained below -

android app screenshot

The current algorithm:

  • The current coordinates of a letter tile are: mRect.top and mRect.left

  • The end destination coordinates are: mTarget.x and mTarget.y

  • As long as there are moving tiles, the app screen is redrawn every 30 milliseconds.

When a tile should be moved somewhere in an animated way, the following method calculates the distance and divides it in 8 equal steps:

public void startAnimatedMove(float x, float y) {
    mTarget.x = x;
    mTarget.y = y;
    steps = 8;
    mStepX = (mTarget.x - mRect.left) / steps;
    mStepY = (mTarget.y - mRect.top) / steps;
}

And then when the next 30 milliseconds passed, the tile is moved and drawn in the new position (the last step is special - so that the tile is put exactly at mTarget.x and mTarget.y):

private void nextStep() {
    if (--steps == 0)
        moveTo(mTarget.x, mTarget.y);
    else 
        moveTo(mRect.left + mStepX, mRect.top + mStepY);
}

This works well, but the tiles move with constant velocity, because the mStepX and mStepY are always same distance (represented by red line in the above diagram).

My question:

I would like to change the steps, so that they are small at the start and end of movement - and large in the middle. I.e. I'd like to have a function for "easying in and out".

I think this way movement will look more natural and I think I probably need an x^2 or sin based functions (represented by green line in above diagram), which I would call here:

private void nextStep() {
    if (--steps == 0)
        moveTo(mTarget.x, mTarget.y);
    else 
        moveTo(mRect.left + calcStepX(steps), mRect.top + calcStepY(steps));
}

Please give me some recommendations for such a function (input: step number 0 to 7, output: distance in pixels to move along x- or y-axis), as I am struggling with math here.

1

There are 1 best solutions below

0
On

Okay, I have ended using Easing Equations by Robert Penner.

The jQuery implementation source code have been most easy to read for me.

Trying them out has been comfortable at this Flash app.