javascript - How can i make my HTML canvas dots move more naturally? -


link code pen here

i opinions on how make canvas dots move in more fluid, liquid way.

i've tried limiting direction number of renders (draw()), has improved little! still lacks fluidity, coming across rigid , 'hard-coded'.

this switch statement way direction set, either passed random integer or previous direction.

 switch (direction) {                     case 1:                       star.x--;                       break;                     case 2:                       star.x++;                       break;                     case 3:                       star.y--;                       break;                     case 4:                       star.y++;                       break;                     case 5:                       star.y--;                       star.x--;                       break;                     case 6:                       star.y--;                       star.x++;                       break;                     case 7:                       star.y++;                       star.x++;                       break;                     case 8:                       star.y++;                       star.x--;                       break; } 

thanks!

you can by:

  • generating cardinal spline based on random line points
  • walk along line , plot star on current position

why cardinal spline? cardinal spline generate smooth line between set of points. if has tension value. exaggerating tension value (i.e. outside normal [0,1] range) produce curly lines instead.

snapshot

// draw example lines var ctx = c.getcontext("2d"), p = [0,100, 25,40, 50,70, 75,50, 100,80, 125,32, 150,100, 175,60]; ctx.font = "bold 16px sans-serif";  render(0); render(0.5); render(-2); ctx.settransform(1,0,0,1,0, 110);  render(-2, 3, "segments: 3"); render(-2, 9, "segments: 9"); render(-2, 25, "segments: 25");  function render(t, seg, txt) {   ctx.beginpath();   ctx.moveto(0, 100);   ctx.curve(p, t, seg || 20);   ctx.stroke();   ctx.filltext(txt ? txt : (!t ? "plain poly-line" : "cardinal, tension: " + t), 0, 20);   ctx.translate(200,0); } 

we can take advantage of property , plot point along such line produce liquid-ish movement. movement can refined de/increase segment resolution between each line in spline affect smoothness speed.

other advantages don't have calculate in animation (there initial "peak" when setting points (cache) though), update array pointer , render. , distribution points forces along evenly distributed (invisible) paths.

how implement can vary of course - here 1 example of approach:

example implementation

define star object (it should prototyped sake of demo):

function star(ctx, xseg) {      var points = [],              // holds points cardinal points         cpos = 0, opos = -1,      // positions in line         len,         w = ctx.canvas.width,         x = -10, y = -10;      // iterates , loop point list                 this.animate = function() {         cpos++;          if (cpos > len - 2) {             cpos = 0; opos = -1;         }          var pos = cpos * 2;         x = points[pos];         y = points[pos + 1];          drawstar();     }      // render star     function drawstar() {         ctx.rect(x, y, 2, 2);     }      // generate set of random points, converts     // points cardinal spline (linked script).     function generatepath() {         var w = ctx.canvas.width,             h = ctx.canvas.height,             numofseg = 20,             dh = h / numofseg,             i= 0, l, x, y;          for(; i<= numofseg; i++) {                       x = xseg + w / 8 * math.random();             y = h - (i * dh + ((dh / 2) * math.random() - (dh / 4)));             points.push(x, y);         }          points = curve(points, -2, 200 * math.random() + 100);         l = points.length;          // adjust out of edges         for(i = 0; < l; += 2) if (points[i] > w) points[i] -= w;         len = points.length / 2;         cpos = parseint(len * math.random());     }        generatepath(); } 

full example

function star(ctx, xseg) {    var points = [],              // holds points cardinal points       cpos = 0, opos = -1,      // positions in line       len,       w = ctx.canvas.width,       x = -10, y = -10;    this.animate = function() {     cpos++;     if (cpos > len - 2) {       cpos = 0;  opos = -1;     }      var pos = cpos * 2;     x = points[pos];     y = points[pos + 1];      drawstar();   };    function drawstar() {     ctx.moveto(x + 2, y);     ctx.arc(x, y, 2, 0, math.pi*2);   }    function generatepath() {     var w = ctx.canvas.width,         h = ctx.canvas.height,         numofseg = 20,         dh = h / numofseg,         i= 0, l, x, y;      for(; <= numofseg; i++) {                x = xseg + w / 8 * math.random();       y = h - (i * dh + ((dh / 2) * math.random() - (dh / 4)));       points.push(x, y);     }      points = getcurvepoints(points, -2, (400 * math.random() + 200)|0);     l = points.length;      for(i = 0; < l; += 2) if (points[i] > w) points[i] -= w;     len = points.length / 2;     cpos = (len * math.random())|0;    }   generatepath(); }  // main code var canvas = document.queryselector("canvas"),     ctx = canvas.getcontext("2d"),     stars = [],     numofstars = 100,     segs = canvas.width / numofstars,      = 0,     throttle = 0,     delay = 2;  // create stars for(; < numofstars; i++) stars.push(new star(ctx, * segs - segs));  ctx.fillstyle = "#fff"; ctx.shadowcolor ="#fff"; ctx.shadowblur = 7;  // animate (function animate() {         if (!throttle) {     ctx.clearrect(0, 0, canvas.width, canvas.height);     ctx.beginpath();     for(var = 0; < stars.length; i++) stars[i].animate();     ctx.fill();    }    throttle++;   if (throttle === delay) throttle = 0;    requestanimationframe(animate); })(); 

see code cardinal spline implementation in this answer.

another approach use particles , variate velocity using example sinus function. work optimally may need velocity grid instead affect particle based on location. grid can have random directions , velocities.


Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -