javascript - Inconsistent speed animating with linear interpolation -


i'm trying animate objects around canvas between 2 calculated points. however, method i'm using doesn't seem take account distance between points. example, far distances take same amount of time animate short distances.

what's best method animating objects consistent speed?

/**  * update function called in setinterval. moves boid new position  *  **/ this.update = function(){     context.clearrect(0,0,canvas.width,canvas.height);       this.amount += 0.005;     if (this.amount > 1) this.kill();      this.x = this.origx + (this.destx - this.origx) * this.amount;     this.y = this.origy + (this.desty - this.origy) * this.amount;      this.drawboid();      //console.log(this.x + ' ' + this.y);     } 

you want take approach animate based on time elapsed since last frame, , speed want animate at, in distance-units-per-unit-time.

you have careful when calculating time elapsed; because scheduled setinterval fire every n milliseconds, doesn't mean code fire @ precisely time. worse, setinterval has minimum delay of 4ms, no matter what. really! instead rely on clock @ time code runs.

better still, modern browsers have method called requestanimationframe() calls chunk of code whenever repaint occur. pass callback, , calls method timestamp first argument.

// find browser's implementation of requestanimationframe window.requestanimationframe =   window.requestanimationframe ||    window.mozrequestanimationframe ||   window.webkitrequestanimationframe ||    window.msrequestanimationframe;  // update method var update = function(timestamp) {   context.clearrect(0, 0, canvas.width, canvas.height);    // how time has elapsed since start of animation?   var elapsedtime = timestamp - starttime;    // how far have moved @ time?   var distancetravelled = elapsedtime * speed;   if (distancetravelled >= totaldistance) distancetravelled = totaldistance; // don't overshoot    // how far have moved in each component?   var distancetravelledx = xperunitdistance * distancetravelled;   var distancetravelledy = yperunitdistance * distancetravelled;    // move there!   this.x = math.round(origin.x + distancetravelledx);   this.y = math.round(origin.y + distancetravelledy);    // draw!   this.drawboid();    if (distancetravelled < totaldistance) {     // schedule update called before next repaint     requestanimationframe(update);   } }  // distance want move var distance = 1; // in distance units  // speed want move @ var speed = 0.005 / 1000; // in distance units per millisecond  // storage time when animation started var starttime;  // start point, in distance units var origin = {   x: 0,   y: 0 };  // destination, in distance units var destination = {   x: 100,   y: 75 };  // distance travel var deltax = (destination.x - origin.x); var deltay = (destination.y - origin.y); var totaldistance = math.sqrt( math.pow(deltax, 2) + math.pow(deltay, 2) );  // storage contribution of each component per unit distance var xperunitdistance,     yperunitdistance;  if (totaldistance > 0) {    // start animating!   xperunitdistance = deltax / totaldistance;   yperunitdistance = deltay / totaldistance;    // start time   starttime = window.performance.now ?               // browsers use high-precision timers               (performance.now() + performance.timing.navigationstart) :                date.now(); // fallback don't    update(starttime); } 

update: adam pointed out chrome uses high precision timer. code has been updated.


Comments

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -