📜 ⬆️ ⬇️

Smooth interface animation (easing)

Greetings to all readers!
I want to share with you a simple but effective way to animate the user interface of your application or site. The article presents a ready-made C ++ code that I used to animate iOS and Android applications based on animated sliders.



Here and here you have already seen examples of the use of mathematical formulas for creating smooth animation (easing). For clarity, I translated part of the code in JavaScript and created this page where you can see the result in action. In this simple example, only one slider is used for animation and all interface elements depend on it. You can also set any available animation for all elements of the interface, see the graph and the formula for the animation.

Animation Sliders


Animation sliders are like tracks on a mixing console. In fact, the slider is a number from 0.0 to 1.0, where 0.0 is the beginning of the animation, and 1.0 is its end. This number is substituted into the mathematical formula. Why do we need these sliders? They are needed because usually there are many elements in the interface, everyone needs animation and their movement must begin and end at the same time. But the type of animation and the coordinates of each element on the screen can be different.
')
Types of animations

The slider can also be moved in different ways. Most often, the interface elements appear smoothly when loading, and when switching to another screen, they disappear smoothly. But for versatility, we will add animation in a circle, for example, in your application, sparks or birds fly through the entire screen, as well as animation back and forth - for example, for flashing buttons.

Slider animation function:
#define MAXSLIDES 5 //   #define LOOP_ANIM 1 //   #define FORWBACK_ANIM 2 // - static float slide[MAXSLIDES]={0.0f}; // ,   0.0  1.0 static bool slideback[MAXSLIDES]={false}; // ,     static bool loopback[MAXSLIDES]={false}; //    -,      static void ANIM(int n, float speed=1.0f, bool forw=true, char loop=0){ //n -    //speed -    //forw -     //loop -    if(loopback[n])forw=!forw; //   -         slideback[n]=!forw; //    slide[n]+=fpsf*(forw?speed:-speed); //       ,  fpsf = 1.0/FPS switch(loop){ case LOOP_ANIM: //   if(slide[n]>1.0f)slide[n]-=1.0f; else if(slide[n]<0.0f)slide[n]+=1.0f; break; case FORWBACK_ANIM: // - if(slide[n]>1.0f){ slide[n]=2.0f-slide[n]; loopback[n]=!loopback[n]; }else if(slide[n]<0.0f){ slide[n]=-slide[n]; loopback[n]=!loopback[n]; } break; default: //   0.0  1.0 if(slide[n]>1.0f)slide[n]=1.0f; else if(slide[n]<0.0f)slide[n]=0.0f; break; } } 

Display interface elements
 //  #define LINEAR 0 #define FADEIN 1 #define FADEOUT 2 #define BALL 3 #define SIN 4 #define INCENTER 5 #define FADEBOTH 6 #define FADEBOTH2 7 #define STEPS 8 #define LAMP 9 #define JUMPIN 10 #define JUMPOUT 11 static float A(int n, int type, float s, float e, int typeout=0, float e2=-1000.0f){ // n -    //type -   //s  e -    ,     //typeout -        () //e2 -      () if(n<0){ //       float tmp=s; s=e; e=tmp; n=-n; if(!slideback[n]){ if(typeout)type=typeout; if(e2!=-1000.0f)e=e2; } }else{ //          ,   if(slideback[n]){ if(typeout)type=typeout; if(e2!=-1000.0f)s=e2; } } float x=slide[n]; //    switch(type){ case FADEOUT: x=x*x; break; case FADEIN: x=1.0f-pow(x-1.0f, 2); break; case FADEBOTH: x=pow(sinf(x*M_PI*0.5f), 2); break; case FADEBOTH2: x=pow(sinf(x*M_PI*0.5f), 2); x=pow(sinf(x*M_PI*0.5f), 2); break; case INCENTER: x=tanf(x*2.0f-1.0f)/3.0f+0.5f; break; case BALL:{ float d=sinf((x-1.0f/12.0f)*M_PI*6.0f)*0.65f+0.65f; x=d+sinf(x*M_PI*0.5f)*(1.0fd); }break; case STEPS: x=(int)(x*7.0f)/7.0f; break; case LAMP: x=sinf(pow(expf(1.25fx), 2)*4.0f); if(x>0.0f)x=1.0f; else x=0.0f; break; case JUMPOUT: x=x*x*8.0f/3.0fx*5.0f/3.0f; break; case JUMPIN: x=x-1.0f; x=-x*x*8.0f/3.0fx*5.0f/3.0f+1.0f; break; } //               return s+(es)*x; } 

How to use all this?


 static void mainLoop(){ //      ANIM(1, 1.0f, showPage); //  №1     ,      ANIM(2, 2.0f, true, LOOP_ANIM); //  №2    ,      //   glColor4f(1.0f, 1.0f, 1.0f, A(1, FADEIN, 0.0f, 1.0f)); DrawSomeImage(width/2, A(1, BALL, -150, height/2, FADEIN, height+200)); DrawOtherImage(A(2, INCENTER, -150, width+150), 100); } 

DrawSomeImage (width / 2, A (1, BALL, -100, height / 2, FADEIN, height + 100));
A certain picture is displayed here, let's say this is a logo. On the x-axis, it is displayed in the middle of the screen, and we have it animated. Let us analyze each parameter:
1 - use slider number 1
BALL - a ball-like animation, the logo should jump on top of the screen
Ball animation chart
-100 is the initial coordinate of Y, i.e. at the top of the screen
height / 2 - it means you need to stop in the middle of the screen vertically
The remaining parameters are optional, but then when loading the page, the logo will jump out from above, which looks organically, but when he needs to get back, the animation of the ball will not look quite natural. Therefore, we set the type of reverse animation, so that it is removed smoothly with acceleration, i.e. FADEIN .
Personally, I like it better when the logo flies down and not back up, so we ask where to fly then i. height + 100 .
This is how the logo is displayed in this example .

We also smoothly change the transparency of this image:
glColor4f (1.0f, 1.0f, 1.0f, A (1, FADEIN, 0.0f, 1.0f));
We use the same 1st slider to synchronously change both the transparency and the coordinates. However, the animation type is set to FADEIN (with acceleration) and we change the transparency from 0.0 to 1.0.

DrawOtherImage (A (2, INCENTER, -150, width + 150), 100);
In this case, the picture will fly from left to right across the entire screen, while it will gradually linger in the middle.
2 - use slider number 2, which is played cyclically and twice as fast as slider number 1.
INCENTER - the formula by which the picture is slightly delayed in the middle of the screen
Animation Pause in the Middle
-150 - the initial coordinate in X
width + 150 - final coordinate in X

Another example

  glColor4f(1.0f, 1.0f, 1.0f, A(1, FADEBOTH, 0.0f, 1.0f)); DrawSomeImage1(); glColor4f(1.0f, 1.0f, 1.0f, A(-1, FADEBOTH, 0.0f, 1.0f)); DrawSomeImage2(); 

As you can see, we display two pictures with different transparency. Both times we use the slider number 1 and use the animation with a smooth start and end. Only the sign in the slider number is different. -1 means that this animation will turn upside down and will hide when the slider is 1.0, and leave when the slider is 0.0. Visually, these two pictures will smoothly replace each other.

There are many options for using animations. You can rotate the interface elements, change the transparency, move around the screen, compress, stretch and it will all look smooth and pleasing to the eye. For me personally, these simple functions significantly save time on creating interfaces. It remains only not to overdo it with animations and not to confuse the user. I hope you find the material in this article useful. If you have suggestions for new types of animations - leave comments, I will replenish their list and update the article.

Update

As an additional illustration I created this page . In the same way, you can change the type of animation, watch the formula and graph.

Links to similar libraries
Tweener
Objective-C Library
thanks nukie and Agent_Smith for links

Source: https://habr.com/ru/post/163197/


All Articles