prototype - JavaScript: using cancelAnimationFrame inside requestAnimationFrame loop -


for sake of learning prototyping animate function htmlelements, inspired jquery. animation starts fine, want stop after requestanimationframe's time = duration given in function. using cancelanimationframe inside animation loop, doesn't stop loop.

    htmlelement.prototype.animate = function(properties,duration){          for(prop in properties){              var last = 0,                 fps = 60;              function ani(time){                  requestanimationframe(ani);                 if ((time - last) > fps ){                                            last = time                     console.log(time)                     if(time >= (duration*1000)){                         window.cancelanimationframe(aniloop)                     }                     }             }             var aniloop = requestanimationframe(ani)         }     } 

the function called this

    c.animate({"property":"value"},1) 

at core of problem lies fact you're getting id of first animation frame (the var aniloop = (...) line) , that's you're trying cancel - except each call requestanimationframe has different id, you'd need store return value of last call , cancel instead:

htmlelement.prototype.animate = function(properties,duration) {     "use strict";      var aniloop,         prop,         last = 0,         fps = 60;      (prop in properties) {          function ani(time) {              aniloop = requestanimationframe(ani);             if ((time - last) > fps) {                                        last = time;                 console.log(time);                 if (time >= (duration * 1000)) {                     cancelanimationframe(aniloop);                 }                 }         }         aniloop = requestanimationframe(ani);     } }; 

there are, however, several other problems code need tackled well, otherwise function blow rather thoroughly:

:1 function declaration in loop

i recommend reading differences between function declaration , expression better picture, problem here you're doing function declaration in loop, considered undefined behaviour (some engines replace functions, not, blow up). given animations have single duration given , thus, synchronised, it'd better option iterate on properties animate inside of single animation function, so:

htmlelement.prototype.animate = function(properties,duration) {     "use strict";      var aniloop,         last = 0,         fps = 60;      function ani(time) {          var prop;          aniloop = requestanimationframe(ani);         if ((time - last) > fps) {              last = time;              (prop in properties) {                 console.log(prop + ': ' + time);             }              if (time >= (duration * 1000)) {                 cancelanimationframe(aniloop);             }             }     }     aniloop = requestanimationframe(ani); } 

:2 animation timestamping

as looks currently, animation function not run more 1 frame anyway - if @ requestanimationframe documentation on mdn, you'll notice callback given requestanimationframe given timestamp, i.e. value in milliseconds beginning of unix epoch (1st of january 1970) - therefore condition of time >= (duration * 1000) true. instead of that, register starting time when kick animation off , compare timestamp within callback it, so:

htmlelement.prototype.animate = function(properties,duration) {     "use strict";      var aniloop,         start,         last = 0,         fps = 60;      function ani(time) {          var prop,             progress;          aniloop = requestanimationframe(ani);         if ((time - last) > fps) {              last = time;             progress = time - start;              (prop in properties) {                 console.log(prop + ': ' + progress + ' out of ' + (duration * 1000));             }              // difference between current , starting time             if (progress >= (duration * 1000)) {                 cancelanimationframe(aniloop);             }             }     }     start = date.now();     aniloop = requestanimationframe(ani); } 

:3 animation throttling

this 1 not crucial, still worth consideration - requestanimationframe intended automatically throttled , regulated browser, don't need apply own conditions on whether animation should run (it won't go on 60fps anyway, that's specification's ceiling). instead, should work on difference of current time starting time, make sure animation still ends in correct place if reason, there lag in animation:

htmlelement.prototype.animate = function(properties,duration) {     "use strict";      var aniloop,         start;      function ani(time) {          var prop,             progress;          aniloop = requestanimationframe(ani);         progress = time - start;          (prop in properties) {             console.log(prop + ': ' + progress + ' out of ' + (duration * 1000));         }          // difference between current , starting time         if (progress >= (duration * 1000)) {             cancelanimationframe(aniloop);         }         }     start = date.now();     aniloop = requestanimationframe(ani); } 

Comments

Popular posts from this blog

java - How to specify maven bin in eclipse maven plugin? -

single sign on - Logging into Plone site with credentials passed through HTTP -

php - Why does AJAX not process login form? -