banner



How To Use Animate Function In Javascript

JavaScript animations tin handle things that CSS tin't.

For instance, moving along a complex path, with a timing role different from Bezier curves, or an animation on a canvas.

Using setInterval

An blitheness tin be implemented equally a sequence of frames – usually pocket-sized changes to HTML/CSS properties.

For instance, changing manner.left from 0px to 100px moves the element. And if we increase information technology in setInterval, irresolute by 2px with a tiny delay, like l times per 2nd, so it looks smooth. That'south the aforementioned principle as in the cinema: 24 frames per second is enough to make it expect polish.

The pseudo-code can look like this:

            let timer = setInterval(function() {   if (animation consummate) clearInterval(timer);   else increase style.left by 2px }, 20); // change past 2px every 20ms, about 50 frames per second          

More complete example of the animation:

            let start = Engagement.at present(); // remember get-go time  allow timer = setInterval(function() {   // how much time passed from the start?   let timePassed = Appointment.at present() - start;    if (timePassed >= 2000) {     clearInterval(timer); // terminate the animation afterward 2 seconds     return;   }    // draw the animation at the moment timePassed   depict(timePassed);  }, 20);  // equally timePassed goes from 0 to 2000 // left gets values from 0px to 400px function depict(timePassed) {   railroad train.style.left = timePassed / 5 + 'px'; }          

Click for the demo:

            <!DOCTYPE HTML> <html>  <head>   <manner>     #train {       position: relative;       cursor: pointer;     }   </style> </head>  <body>    <img id="train" src="https://js.cx/clipart/train.gif">     <script>     train.onclick = function() {       allow get-go = Appointment.now();        permit timer = setInterval(function() {         let timePassed = Engagement.now() - get-go;          railroad train.style.left = timePassed / v + 'px';          if (timePassed > 2000) clearInterval(timer);        }, 20);     }   </script>   </body>  </html>          

Using requestAnimationFrame

Let's imagine we take several animations running simultaneously.

If we run them separately, then even though each one has setInterval(..., 20), then the browser would have to repaint much more than often than every 20ms.

That'south because they have different starting time, then "every 20ms" differs between unlike animations. The intervals are not aligned. So we'll take several independent runs within 20ms.

In other words, this:

            setInterval(function() {   animate1();   animate2();   animate3(); }, 20)          

…Is lighter than three independent calls:

            setInterval(animate1, 20); // contained animations setInterval(animate2, 20); // in different places of the script setInterval(animate3, 20);          

These several independent redraws should be grouped together, to make the redraw easier for the browser and hence load less CPU load and await smoother.

There's 1 more thing to continue in mind. Sometimes CPU is overloaded, or there are other reasons to redraw less often (like when the browser tab is subconscious), so we really shouldn't run information technology every 20ms.

Merely how practice we know virtually that in JavaScript? There's a specification Animation timing that provides the function requestAnimationFrame. Information technology addresses all these issues and even more than.

The syntax:

            permit requestId = requestAnimationFrame(callback)          

That schedules the callback office to run in the closest time when the browser wants to do animation.

If we do changes in elements in callback then they will be grouped together with other requestAnimationFrame callbacks and with CSS animations. And then there will be one geometry recalculation and repaint instead of many.

The returned value requestId can exist used to cancel the call:

            // cancel the scheduled execution of callback cancelAnimationFrame(requestId);          

The callback gets one argument – the time passed from the beginning of the page load in milliseconds. This time can as well be obtained by calling operation.at present().

Usually callback runs very soon, unless the CPU is overloaded or the laptop battery is near discharged, or in that location's some other reason.

The code beneath shows the fourth dimension between first 10 runs for requestAnimationFrame. Usually information technology's 10-20ms:

            <script>   let prev = operation.now();   let times = 0;    requestAnimationFrame(function measure(fourth dimension) {     document.body.insertAdjacentHTML("beforeEnd", Math.floor(time - prev) + " ");     prev = time;      if (times++ < 10) requestAnimationFrame(measure);   }) </script>          

Structured animation

At present we can make a more universal blitheness role based on requestAnimationFrame:

            function animate({timing, depict, duration}) {    let start = performance.at present();    requestAnimationFrame(role animate(fourth dimension) {     // timeFraction goes from 0 to i     permit timeFraction = (time - start) / elapsing;     if (timeFraction > one) timeFraction = ane;      // calculate the current animation state     let progress = timing(timeFraction)      describe(progress); // draw information technology      if (timeFraction < 1) {       requestAnimationFrame(animate);     }    }); }          

Office breathing accepts 3 parameters that essentially describes the blitheness:

elapsing

Total time of animation. Like, chiliad.

timing(timeFraction)

Timing office, like CSS-property transition-timing-function that gets the fraction of time that passed (0 at start, one at the end) and returns the animation completion (like y on the Bezier curve).

For instance, a linear function means that the animation goes on uniformly with the same speed:

                part linear(timeFraction) {   return timeFraction; }              

Its graph:

That's but similar transition-timing-function: linear. At that place are more interesting variants shown beneath.

draw(progress)

The function that takes the blitheness completion country and draws it. The value progress=0 denotes the offset animation state, and progress=i – the stop state.

This is that function that actually draws out the blitheness.

It tin move the chemical element:

                function draw(progress) {   train.style.left = progress + 'px'; }              

…Or do anything else, nosotros can animate annihilation, in any mode.

Let'due south animate the element width from 0 to 100% using our function.

Click on the element for the demo:

              office animate({elapsing, draw, timing}) {    let start = functioning.now();    requestAnimationFrame(function animate(time) {     permit timeFraction = (time - start) / duration;     if (timeFraction > 1) timeFraction = i;      allow progress = timing(timeFraction)      describe(progress);      if (timeFraction < ane) {       requestAnimationFrame(animate);     }    }); }            
              <!DOCTYPE HTML> <html>  <head>   <meta charset="utf-8">   <style>     progress {       width: 5%;     }   </way>   <script src="breathing.js"></script> </caput>  <body>     <progress id="elem"></progress>    <script>     elem.onclick = function() {       animate({         elapsing: 1000,         timing: function(timeFraction) {           return timeFraction;         },         describe: function(progress) {           elem.manner.width = progress * 100 + '%';         }       });     };   </script>   </body>  </html>            

The code for information technology:

            animate({   elapsing: yard,   timing(timeFraction) {     return timeFraction;   },   draw(progress) {     elem.way.width = progress * 100 + '%';   } });          

Dissimilar CSS animation, nosotros tin can make any timing role and any drawing function here. The timing function is not express past Bezier curves. And draw can go beyond backdrop, create new elements for like fireworks animation or something.

Timing functions

We saw the simplest, linear timing part above.

Let'southward see more of them. We'll try movement animations with different timing functions to run across how they piece of work.

Power of n

If we want to speed up the animation, we can use progress in the power n.

For instance, a parabolic bend:

            function quad(timeFraction) {   render Math.pow(timeFraction, 2) }          

The graph:

See in action (click to activate):

…Or the cubic bend or even greater northward. Increasing the power makes information technology speed up faster.

Here'south the graph for progress in the ability 5:

In activity:

The arc

Office:

            role circ(timeFraction) {   return 1 - Math.sin(Math.acos(timeFraction)); }          

The graph:

Back: bow shooting

This function does the "bow shooting". Beginning nosotros "pull the bowstring", and and then "shoot".

Unlike previous functions, it depends on an additional parameter x, the "elasticity coefficient". The distance of "bowstring pulling" is defined by it.

The lawmaking:

            function back(x, timeFraction) {   return Math.pw(timeFraction, two) * ((10 + 1) * timeFraction - x) }          

The graph for x = one.5:

For animation we use information technology with a specific value of 10. Instance for x = i.5:

Bounciness

Imagine nosotros are dropping a ball. Information technology falls down, then bounces dorsum a few times and stops.

The bounce office does the same, but in the contrary order: "bouncing" starts immediately. Information technology uses few special coefficients for that:

            office bounce(timeFraction) {   for (allow a = 0, b = 1; ane; a += b, b /= ii) {     if (timeFraction >= (7 - 4 * a) / eleven) {       return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pw(b, 2)     }   } }          

In action:

Elastic animation

One more than "elastic" role that accepts an additional parameter x for the "initial range".

            function elastic(x, timeFraction) {   return Math.pow(ii, 10 * (timeFraction - 1)) * Math.cos(20 * Math.PI * x / 3 * timeFraction) }          

The graph for x=1.5:

In action for x=1.five:

Reversal: ease*

So we have a collection of timing functions. Their straight application is chosen "easeIn".

Sometimes we need to testify the blitheness in the reverse lodge. That's washed with the "easeOut" transform.

easeOut

In the "easeOut" mode the timing role is put into a wrapper timingEaseOut:

            timingEaseOut(timeFraction) = 1 - timing(i - timeFraction)          

In other words, we accept a "transform" function makeEaseOut that takes a "regular" timing function and returns the wrapper effectually information technology:

            // accepts a timing function, returns the transformed variant role makeEaseOut(timing) {   return function(timeFraction) {     return i - timing(1 - timeFraction);   } }          

For instance, nosotros tin can accept the bounciness part described above and apply it:

            let bounceEaseOut = makeEaseOut(bounce);          

Then the bounce will be not in the showtime, merely at the cease of the animation. Looks even better:

              #brick {   width: 40px;   pinnacle: 20px;   groundwork: #EE6B47;   position: relative;   cursor: pointer; }  #path {   outline: 1px solid #E8C48E;   width: 540px;   height: 20px; }            
              <!DOCTYPE HTML> <html>  <head>   <meta charset="utf-8">   <link rel="stylesheet" href="way.css">   <script src="https://js.cx/libs/animate.js"></script> </caput>  <trunk>     <div id="path">     <div id="brick"></div>   </div>    <script>     part makeEaseOut(timing) {       render function(timeFraction) {         return 1 - timing(i - timeFraction);       }     }      role bounciness(timeFraction) {       for (let a = 0, b = 1; 1; a += b, b /= 2) {         if (timeFraction >= (7 - four * a) / 11) {           return -Math.prisoner of war((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, two)         }       }     }      let bounceEaseOut = makeEaseOut(bounce);      brick.onclick = function() {       breathing({         elapsing: 3000,         timing: bounceEaseOut,         draw: function(progress) {           brick.style.left = progress * 500 + 'px';         }       });     };   </script>   </torso>  </html>            

Here we tin see how the transform changes the behavior of the role:

If at that place's an animation effect in the beginning, like bouncing – it will be shown at the cease.

In the graph above the regular bounce has the red color, and the easeOut bounce is blue.

  • Regular bounce – the object bounces at the bottom, so at the end sharply jumps to the pinnacle.
  • Subsequently easeOut – it outset jumps to the summit, then bounces there.

easeInOut

We also tin can show the effect both in the showtime and the stop of the blitheness. The transform is chosen "easeInOut".

Given the timing office, we calculate the animation land like this:

            if (timeFraction <= 0.five) { // offset half of the blitheness   return timing(2 * timeFraction) / 2; } else { // second half of the animation   return (2 - timing(2 * (ane - timeFraction))) / ii; }          

The wrapper code:

            function makeEaseInOut(timing) {   render function(timeFraction) {     if (timeFraction < .5)       return timing(two * timeFraction) / 2;     else       return (2 - timing(2 * (1 - timeFraction))) / 2;   } }  bounceEaseInOut = makeEaseInOut(bounce);          

In action, bounceEaseInOut:

              #brick {   width: 40px;   height: 20px;   background: #EE6B47;   position: relative;   cursor: arrow; }  #path {   outline: 1px solid #E8C48E;   width: 540px;   peak: 20px; }            
              <!DOCTYPE HTML> <html>  <head>   <meta charset="utf-viii">   <link rel="stylesheet" href="style.css">   <script src="https://js.cx/libs/animate.js"></script> </head>  <body>     <div id="path">     <div id="brick"></div>   </div>    <script>     function makeEaseInOut(timing) {       return office(timeFraction) {         if (timeFraction < .5)           render timing(two * timeFraction) / ii;         else           return (2 - timing(two * (1 - timeFraction))) / ii;       }     }       function bounce(timeFraction) {       for (let a = 0, b = 1; 1; a += b, b /= ii) {         if (timeFraction >= (seven - iv * a) / 11) {           return -Math.pow((11 - 6 * a - 11 * timeFraction) / iv, 2) + Math.prisoner of war(b, two)         }       }     }      permit bounceEaseInOut = makeEaseInOut(bounce);      brick.onclick = function() {       animate({         duration: 3000,         timing: bounceEaseInOut,         draw: function(progress) {           brick.style.left = progress * 500 + 'px';         }       });     };   </script>   </trunk>  </html>            

The "easeInOut" transform joins two graphs into one: easeIn (regular) for the first one-half of the animation and easeOut (reversed) – for the second part.

The effect is clearly seen if we compare the graphs of easeIn, easeOut and easeInOut of the circ timing function:

  • Reddish is the regular variant of circ (easeIn).
  • Light-greeneaseOut.
  • BlueeaseInOut.

As we tin can see, the graph of the showtime one-half of the animation is the scaled downwardly easeIn, and the second half is the scaled down easeOut. Equally a result, the animation starts and finishes with the aforementioned issue.

More interesting "describe"

Instead of moving the chemical element we can do something else. All we need is to write the proper depict.

Here'southward the animated "bouncing" text typing:

              textarea {   brandish: block;   border: 1px solid #BBB;   color: #444;   font-size: 110%; }  button {   margin-top: 10px; }            
              <!DOCTYPE HTML> <html>  <head>   <meta charset="utf-eight">   <link rel="stylesheet" href="style.css">   <script src="https://js.cx/libs/animate.js"></script> </head>  <body>     <textarea id="textExample" rows="5" cols="lx">He took his vorpal sword in hand: Long time the manxome foe he sought— So rested he past the Tumtum tree, And stood awhile in thought.   </textarea>    <push onclick="animateText(textExample)">Run the animated typing!</button>    <script>     function animateText(textArea) {       permit text = textArea.value;       let to = text.length,         from = 0;        animate({         duration: 5000,         timing: bounce,         draw: part(progress) {           let result = (to - from) * progress + from;           textArea.value = text.substr(0, Math.ceil(result))         }       });     }       part bounce(timeFraction) {       for (let a = 0, b = 1; 1; a += b, b /= ii) {         if (timeFraction >= (vii - 4 * a) / xi) {           return -Math.pow((11 - 6 * a - 11 * timeFraction) / four, 2) + Math.pow(b, 2)         }       }     }   </script>   </torso>  </html>            

Summary

For animations that CSS can't handle well, or those that need tight command, JavaScript tin can help. JavaScript animations should be implemented via requestAnimationFrame. That built-in method allows to setup a callback role to run when the browser will be preparing a repaint. Usually that'southward very shortly, but the exact time depends on the browser.

When a page is in the background, in that location are no repaints at all, so the callback won't run: the animation will be suspended and won't swallow resource. That's great.

Here's the helper animate function to setup most animations:

            function animate({timing, draw, duration}) {    let start = performance.now();    requestAnimationFrame(office breathing(time) {     // timeFraction goes from 0 to 1     let timeFraction = (time - showtime) / duration;     if (timeFraction > 1) timeFraction = i;      // calculate the current animation land     permit progress = timing(timeFraction);      describe(progress); // draw it      if (timeFraction < 1) {       requestAnimationFrame(breathing);     }    }); }          

Options:

  • duration – the total animation time in ms.
  • timing – the role to summate animation progress. Gets a time fraction from 0 to one, returns the blitheness progress, usually from 0 to one.
  • draw – the function to draw the blitheness.

Surely we could improve it, add more bells and whistles, but JavaScript animations are not practical on a daily basis. They are used to practice something interesting and non-standard. So you'd desire to add the features that yous need when you need them.

JavaScript animations can use any timing function. We covered a lot of examples and transformations to make them even more versatile. Unlike CSS, we are not limited to Bezier curves here.

The aforementioned is about draw: we can animate anything, not just CSS properties.

Source: https://javascript.info/js-animation

Posted by: gaultgrabusereave1955.blogspot.com

0 Response to "How To Use Animate Function In Javascript"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel