473,508 Members | 2,032 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Using an animation function written in native JavaScript on Alibaba Cloud

51 New Member
Problems during numerical calculation using an animation function written in native JavaScript

I tried to write a code when learning the MOOC online JavaScript animation effect. But I found several problems:
Non-uniform animation velocity
Animation duration was not able to be controlled
Other actions started before the animation reached the terminating condition (especially during transparency changes. The super-long decimal point calculation – as many as eight to nine decimal places – of JavaScript just left me speechless.)
Can somebody help me modify the code? Thanks so much.
If somebody can write a concise native JavaScript animation function that enables interaction of multiple attributes for reference, that would be even more awesome. (Please do make the animation duration controllable and animation termination strictly following the given conditions.)
Here is the code:
Expand|Select|Wrap|Line Numbers
  1. <!doctype html>
  2.     <html lang="en">
  3.      <head>
  4.    <meta http-equiv='content-type' content='text/html;charset=utf-8' />
  5.       <script>
  6.     /*--Get the ID--*/
  7.     function $id(id){
  8.       return document.getElementById(id);
  9.     }
  10.     /*----Get the element style attributes--*/
  11.     function $gs(ele,attr){
  12.        if (ele.currentStyle)
  13.          {
  14.            return ele.currentStyle[attr];
  15.          }else if (ele.style[attr]!==''){
  16.               return ele.style[attr];
  17.          }else{
  18.           if (window.getComputedStyle(ele,null)[attr]!=='auto')
  19.            {
  20.              return window.getComputedStyle(ele,null)[attr];
  21.            }else{
  22.              return 0;
  23.            }
  24.          }
  25.     } 
  26.  
  27.         // Multi-attribute animation
  28.         function animate(ele,time,json,fn){
  29.            window.clearInterval(ele.timer);
  30.            var fps=60/1000;
  31.            ele.timer=window.setInterval(function(){
  32.               for (var a in json)
  33.                {
  34.                  var curVal=(a.search('opacity')!==-1) ? parseFloat($gs(ele,a)) :parseInt($gs(ele,a)); // $gs 是自定义的获取元素某样式值德函数
  35.                  var unit=(a.search('opacity')!==-1) ? '' : 'px';
  36.                  var speed=(json[a]-curVal)/(fps*time);
  37.                  if (speed>=0){
  38.  
  39.                    if (curVal>=json[a]){
  40.                      window.clearInterval(ele.timer);
  41.                      ele.style[a]=json[a]+unit;
  42.                      if (fn){
  43.                        fn();
  44.                      }
  45.                    }else{
  46.                      ele.style[a]=curVal+speed+unit;
  47.                    }
  48.                  }else{
  49.                    if (curVal<=json[a]+0.05){
  50.                      window.clearInterval(ele.timer);
  51.                      ele.style[a]=json[a]+unit;
  52.                      if (fn){
  53.                        fn();
  54.                      }
  55.                    }else{
  56.                      ele.style[a]=curVal+speed+unit;
  57.                    }
  58.                  }
  59.                }
  60.            },1/fps);
  61.         }
  62.  
  63.      </script>
  64.      </head>
  65.      <body>
  66.        <style>
  67.          #animate{width:200px;height:200px;background-color:blue;}
  68.        </style>
  69.        <div id='animate'></div>
  70.  
  71.        <button id='pos'>Start the multi-attribute interaction animation </button>
  72.        <script>
  73.          $id('pos').onclick=function(){  // $id(id) is the custom function for quick retrieval of elements
  74.            animate($id('animate'),1000,{width:500,opacity:0},function(){
  75.              animate($id('animate'),1000,{width:200,opacity:1});
  76.            });
  77.          }
  78.        </script>
  79.      </body>
  80.     </html>
Apr 20 '18 #1
4 1932
gits
5,390 Recognized Expert Moderator Expert
well - i just reused the code that you posted to come up with a refactored version that would simply use the duration to determine and control the simultaneous animation of some properties - which i was thinking was what you were looking for. you can have a look at it and see if it fits to what you want it to behave. It has a linear animation speed and combines the properties all at once. I am sure i didn't code it for all cases that might happen - but its not intended - its just as an example how i would think that the duration would determine the animation. was hard enough to write it that 'function-like-way' anyway - since i usually would build classes for that. but that might have been confusing here - so i kept it same style as your posted code came.

Expand|Select|Wrap|Line Numbers
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta http-equiv='content-type' content='text/html;charset=utf-8' />
  5.     <script>
  6.  
  7.     function $id(id){
  8.         return document.getElementById(id);
  9.     }
  10.  
  11.     function getEleStyle(ele, prop) {
  12.         return window.getComputedStyle(ele, null).getPropertyValue(prop);
  13.     }
  14.  
  15.     /**
  16.      * function animate
  17.      *
  18.      * @param ele dom-node
  19.      * @param duration duration in ms
  20.      * @param props js-obj with css props to set the values to
  21.      * @param cb optional callback that is called when the animation is over
  22.      */
  23.     function animate(ele, duration, props, cb) {
  24.  
  25.         // calculate how many frames we need to process for this animation
  26.         // note: i consider a frame as ONE interval cycle
  27.         var fps = 60;
  28.         var intervalStep = 1000/fps;
  29.         var framesToRenderAtAll = duration/1000 * fps;
  30.         var currFrame = 0;
  31.  
  32.         // scale the passed props according to the frames we have to 
  33.         // process
  34.         var propSteps = {};
  35.  
  36.         for (var prop in props) {
  37.             propSteps[prop] = {};
  38.  
  39.             var propStart = getEleStyle(ele, prop);
  40.             var pxTest = /px$/.test(propStart);
  41.  
  42.             propSteps[prop].unit = pxTest ? 'px' : '';
  43.             propSteps[prop].curr = pxTest ? parseInt(propStart, 10) : parseFloat(propStart);
  44.  
  45.             var step = (props[prop] - propSteps[prop].curr)/framesToRenderAtAll;
  46.  
  47.             propSteps[prop].step = parseFloat(step.toFixed(2));
  48.         }
  49.  
  50.         // function to set the props per animation-frame    
  51.         var setProps = function() {
  52.             currFrame++;
  53.  
  54.             for (var i in propSteps) {
  55.                 propSteps[i].curr += propSteps[i].step;
  56.                 ele.style[i] = propSteps[i].curr + propSteps[i].unit;
  57.             }
  58.  
  59.             if (currFrame >= framesToRenderAtAll) {
  60.                 window.clearInterval(t);
  61.  
  62.                 if (typeof cb != 'undefined') {
  63.                     cb();
  64.                 }
  65.             }
  66.         };
  67.  
  68.         // instantly call first step
  69.         setProps();
  70.  
  71.         // setting the interval to start the animation
  72.         var t = window.setInterval(setProps, intervalStep);
  73.     }
  74.  
  75.     </script>
  76. </head>
  77. <body>
  78.     <style>
  79.         #animate{width:200px;height:200px;background-color:blue;}
  80.     </style>
  81.     <div id='animate'></div>
  82.     <button id='pos'>Start the multi-attribute interaction animation</button>
  83.     <script>
  84.  
  85.     $id('pos').onclick = function() {
  86.         animate($id('animate'), 1000, {width:1000, opacity:0, height:100}, function() {
  87.             animate($id('animate'), 1000, {width:200, opacity:1, height:200});
  88.         });
  89.     }
  90.  
  91.     </script>
  92. </body>
  93. </html>
PS: it is not as exact as it could be in determining exact steps and such - but you can improve it by more rounding floats and such where necessary.
Apr 20 '18 #2
TimoHa
22 New Member
You set the default FPS value to 60. Speed indicates the rate at which each frame will change.
However, the number of frames in a browser is not certain because of a variety of factors, and the time intervals between frames are also undefined.
The actual animation process should be calculated by the time difference between the start time and the current time.
When the animate function runs, it retrieves the start time from Date.now(). In the setInterval method, it retrieves the current time from Date.now() every time.
Calculate the proportion of the time gap “elapsed” between the two values to the animation time variable “time”, and you can get the variation proportion of the style.
I will post the code later today if I have the time.
Here is the code.
Multi-attribute animation
Expand|Select|Wrap|Line Numbers
  1. var interval = 1000 / 60;
  2. var animate = function animate(ele, time, json, fn) {
  3.     if (ele.timer) return;
  4.     var startTime = Date.now(),
  5.         vals = [];
  6.     for (var key in json) {
  7.         var curVal = key.search('opacity') !== -1 ? parseFloat($gs(ele, key)) : parseInt($gs(ele, key)),
  8.             unit = key.search('opacity') !== -1 ? '' : 'px';
  9.  
  10.         vals.push({ style: key, startVal: curVal, endVal: json[key], unit: unit });
  11.     }
  12.  
  13.     ele.timer = setInterval(function () {
  14.         var elapsed = Date.now() - startTime;
  15.         if (elapsed >= time) {
  16.             clearInterval(ele.timer);
  17.             ele.timer = null;
  18.             for (var i = 0; i < vals.length; i++) {
  19.                 ele.style[vals[i].style] = vals[i].endVal + vals[i].unit;
  20.             }
  21.  
  22.             fn && fn();
  23.         } else {
  24.             for (var i = 0; i < vals.length; i++) {
  25.                 ele.style[vals[i].style] = vals[i].startVal + (vals[i].endVal - vals[i].startVal) * (elapsed / time) + vals[i].unit;
  26.             }
  27.         }
  28.     }, interval);
  29. };
  30.  
Apr 23 '18 #3
gits
5,390 Recognized Expert Moderator Expert
well - seems viable solution as well - while i work with a constant number of frames TimoHa's solution assumes that the elapsed time isn't exactly the time of the interval - which is correct - so it can end up drawing a bit more or less calculated frames. Basically TimoHa's solution is better since it can smooth out some processing delays and such - it can be easily simulated by just placing a longer loop into the prop-setter-function - with my solution it will lead to a longer animation (constant number of frames) while the other solution determines the remaining time and adapts - so its a more constant duration.
Apr 23 '18 #4
gits
5,390 Recognized Expert Moderator Expert
here is something that can be very useful for such tasks since it explains in more detail what happens exactly and how things can be optimized especially with animations:

THE EVENT LOOP

cheers,
gits
May 22 '18 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

3
2898
by: BibhuAshish | last post by:
Hello guys i have one function which converts the ip/netmask into networkid/netmask and also it shows the message to user that his ip is changed to network id. but that function is working in...
0
2127
by: Dan1701 | last post by:
Is building a Hadoop cluster on Alibaba Cloud with CM + CDH supported?
0
2743
by: IvanH | last post by:
Does Alibaba Cloud ECS Automatic Backup Occupy Server Space?*
0
2803
by: IvanH | last post by:
Can Alibaba Cloud ECS defend against attacks?*
0
2759
by: IvanH | last post by:
What lines are used by Alibaba Cloud ECS?*
0
2731
by: IvanH | last post by:
Does Alibaba Cloud have CDN service?
0
2755
by: IvanH | last post by:
Can OS be Switched or Automatically Added/Upgraded on Alibaba Cloud?
0
3614
by: IvanH | last post by:
https://www.decent.vip My website uses Alibaba Cloud OSS and Alibaba Cloud CDN for Wordpress.It said I can visit this page but it returns a 403 error. And the icon is not there. What can I do?
0
3347
by: IvanH | last post by:
unable to access the instance remotely using rdp on Alibaba Cloud ECS, please help.
0
3676
by: IvanH | last post by:
How Can I Migrate from F(x) Data Cloud to Alibaba Cloud when I do web hosting?
0
7226
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7388
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7049
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
5055
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3199
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3186
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1561
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
767
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
422
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.