javascript - Acceleration setInterval in Jquery -


i trying create bouncing ball (on canvas). love if ball accelerate when going , down. no idea how setinterval. here code:

setinterval(function animate() {     ctx.clearrect( 0, 0, canvas.width, canvas.height);      if (movement1 === true) {         dotheight += 1;         if (dotheight >= 100) movement1 = false;     } else {         dotheight -= 1;         if (dotheight <= 0) movement1 = true;     }         ctx.beginpath();         ctx.arc(canvas.width / 2, (canvas.height / 2) + dotheight, dotsize, 0, 2 * math.pi);         ctx.fillstyle = "white";         ctx.fill();     }, 4); 

this results in linear movement. love have natural movement. starting fast , getting slower when reaching top , vice versa.

you should have both speed , gravity (or acceleration) variable:

  • speed tells how many units (pixels here) going travel object in the current update.
  • gravity tells how many units speed increased on each update.

you want constant gravity speed increasing same amount of pixels on each update. give variable speed, object (dot here) travelling longer or shorter distances on each update, depending on direction travelling.

to make dot bounce change direction of speed once reaches floor. need multiply -1 or, instead of that, multiply bouncingfactor (-1 < bouncingfactor < 0) loses energy on each bounce:

enter image description here

here can see working example:

var canvas = document.getelementbyid("canvas");  canvas.width = canvas.offsetwidth;  canvas.height = canvas.offsetheight;    var ctx = canvas.getcontext("2d");  var frames = 0; // frame counter make sure don't crash browser while editing code!    // dot stuff:    var dotsize = 20;  var dotminy = 0 + dotsize; // start position  var dotmaxy = canvas.height - dotsize; // floor  var doty = dotminy;  var dotspeed = 0;  var dotlastbouncespeed = 0; // can use determine whether ball still bouncing enough visible user.    var center = canvas.width / 2; // try take every operation can out of animate function.  var pi2 = 2 * math.pi;    // world stuff:    var gravity = .5;  var bouncefactor = .8; // if < 1, bouncing absorbs energy ball won't go high before.    // main animation loop:    function animate() {    ctx.clearrect( 0, 0, canvas.width, canvas.height);      ctx.beginpath();    ctx.arc(center, doty, dotsize, 0, pi2);    ctx.fillstyle = "red";    ctx.fill();      // first, dotspeed += gravity calculated , returns new value dotspeed    // then, new value added doty.    doty += dotspeed += gravity;         if(doty >= dotmaxy ) {      doty = dotmaxy;      dotspeed *= -bouncefactor;      }      var dotcurrentbouncespeed = math.round(dotspeed * 100); // takes 2 decimal digits.        if(frames++ < 5000 && dotlastbouncespeed != dotcurrentbouncespeed) {      dotlastbouncespeed = dotcurrentbouncespeed;      settimeout(animate, 16); // 1000/60 = 16.6666...    }    else alert("animation end. took " + frames + " frames.");  }    animate();
html, body, #canvas {    position:relative;    width: 100%;    height: 100%;    margin: 0;    overflow:hidden;  }
<canvas id="canvas"></canvas>

you should consider using requestanimationframe insted of settimeout. mdn doc:

the window.requestanimationframe() method tells browser wish perform animation , requests browser call specified function update animation before next repaint. method takes argument callback invoked before repaint.

the same example requestanimationframe:

var canvas = document.getelementbyid("canvas");  canvas.width = canvas.offsetwidth;  canvas.height = canvas.offsetheight;    var ctx = canvas.getcontext("2d");  var frames = 0; // frame counter make sure don't crash browser while editing code!    // dot stuff:    var dotsize = 20;  var dotminy = 0 + dotsize; // start position  var dotmaxy = canvas.height - dotsize; // floor  var doty = dotminy;  var dotspeed = 0;  var dotlastbouncespeed = 0; // can use determine whether ball still bouncing enough visible user.    var center = canvas.width / 2; // try take every operation can out of animate function.  var pi2 = 2 * math.pi;    // world stuff:    var gravity = .5;  var bouncefactor = .8; // if < 1, bouncing absorbs energy ball won't go high before.    // main animation loop:    function animate() {    ctx.clearrect( 0, 0, canvas.width, canvas.height);      ctx.beginpath();    ctx.arc(center, doty, dotsize, 0, pi2);    ctx.fillstyle = "red";    ctx.fill();      // first, dotspeed += gravity calculated , returns new value dotspeed    // then, new value added doty.    doty += dotspeed += gravity;         if(doty >= dotmaxy ) {      doty = dotmaxy;      dotspeed *= -bouncefactor;      }      var dotcurrentbouncespeed = math.round(dotspeed * 100); // takes 2 decimal digits.        if(frames++ < 5000 && dotlastbouncespeed != dotcurrentbouncespeed) {      dotlastbouncespeed = dotcurrentbouncespeed;      //settimeout(animate, 10);      window.requestanimationframe(animate); // better!!    }    else alert("animation end. took " + frames + " frames.");  }    animate();
html, body, #canvas {    position:relative;    width: 100%;    height: 100%;    margin: 0;    overflow:hidden;  }
<canvas id="canvas"></canvas>

as can see, need change 1 line of code! however, may need polyfill fall settimeout if browser not support requestanimationframe.

you can learn more requestanimationframe in this post. explains basics , how set custom frame rate.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -