Draw responsive particles on canvas by javascript

252 Views Asked by At

I want to change these code so that it would be responsive and changing the browser size won't be an issue

first code: i need change this to responsive

var canvasDots = function() {
  var canvas = document.querySelector('canvas'),
      ctx = canvas.getContext('2d'),
      colorDot = '#00bdbf',
      color = '#00bdbf';
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  canvas.style.display = 'block';
  ctx.fillStyle = colorDot;
  ctx.lineWidth = .1;
  ctx.strokeStyle = color;

  var mousePosition = {
    x: 30 * canvas.width / 100,
    y: 30 * canvas.height / 100
  };

  var dots = {
    nb: 350,
    distance: 60,
    d_radius: 100,
    array: []
  };

  function Dot(){
    this.x = Math.random() * canvas.width;
    this.y = Math.random() * canvas.height;

    this.vx = -.5 + Math.random();
    this.vy = -.5 + Math.random();

    this.radius = Math.random();
  }

  Dot.prototype = {
    create: function(){
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fill();
    },

    animate: function(){
      for(i = 0; i < dots.nb; i++){

        var dot = dots.array[i];

        if(dot.y < 0 || dot.y > canvas.height){
          dot.vx = dot.vx;
          dot.vy = - dot.vy;
        }
        else if(dot.x < 0 || dot.x > canvas.width){
          dot.vx = - dot.vx;
          dot.vy = dot.vy;
        }
        dot.x += dot.vx;
        dot.y += dot.vy;
      }
    },

    line: function(){
      for(i = 0; i < dots.nb; i++){
        for(j = 0; j < dots.nb; j++){
          i_dot = dots.array[i];
          j_dot = dots.array[j];

          if((i_dot.x - j_dot.x) < dots.distance && (i_dot.y - j_dot.y) < dots.distance && (i_dot.x - j_dot.x) > - dots.distance && (i_dot.y - j_dot.y) > - dots.distance){
            if((i_dot.x - mousePosition.x) < dots.d_radius && (i_dot.y - mousePosition.y) < dots.d_radius && (i_dot.x - mousePosition.x) > - dots.d_radius && (i_dot.y - mousePosition.y) > - dots.d_radius){
              ctx.beginPath();
              ctx.moveTo(i_dot.x, i_dot.y);
              ctx.lineTo(j_dot.x, j_dot.y);
              ctx.stroke();
              ctx.closePath();
            }
          }
        }
      }
    }
  };

  function createDots(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for(i = 0; i < dots.nb; i++){
      dots.array.push(new Dot());
      dot = dots.array[i];

      dot.create();
    }

    dot.line();
    dot.animate();
  }

  window.onmousemove = function(parameter) {
    mousePosition.x = parameter.pageX;
    mousePosition.y = parameter.pageY;
  }

  mousePosition.x = window.innerWidth / 2;
  mousePosition.y = window.innerHeight / 2;

  setInterval(createDots, 1000/30); 
};

window.onload = function() {
  canvasDots();
};
html, body {
  background: #333;
}
canvas{
  position: absolute;
  width: 100%; height: 100%;
  top: 0; right: 0; bottom: 0; left: 0;
}
<canvas></canvas>

seconde code: i need change this to responsive

var livePatern = {
  canvas: null,
  context: null,
  cols: 0,
  rows: 0,
  colors: [252, 251, 249, 248, 241, 240],
  triangleColors: [],
  destColors: [],
  
  init: function(){
    this.canvas = document.getElementById('canvas');
    this.context = this.canvas.getContext('2d');
    this.cols = Math.floor(document.body.clientWidth / 24);
    this.rows = Math.floor(document.body.clientHeight / 24) + 1;
    
    this.canvas.width = document.body.clientWidth;
    this.canvas.height = document.body.clientHeight;
    
    this.drawBackground();
    this.animate();
  },
  
  drawTriangle: function(x, y, color, inverted){
    inverted = inverted == undefined ? false : inverted;

    this.context.beginPath();
    this.context.moveTo(x, y);
    this.context.lineTo(inverted ? x - 22 : x + 22, y + 11);
    this.context.lineTo(x, y + 22);
    this.context.fillStyle = "rgb("+color+","+color+","+color+")";
    this.context.fill();
    this.context.closePath();
  },
  
  getColor: function(){    
    return this.colors[(Math.floor(Math.random() * 6))];
  },
  
  drawBackground: function(){
    var eq = null;
    var x = this.cols;
    var destY = 0;
    var color, y;
    
    while(x--){
      eq = x % 2;
      y = this.rows;

      while(y--){
        destY = Math.round((y-0.5) * 24);

        this.drawTriangle(x * 24 + 2, eq == 1 ? destY : y * 24, this.getColor());
        this.drawTriangle(x * 24, eq == 1 ? destY  : y * 24, this.getColor(), true);
      }
    }
  },
  
  animate: function(){
    var me = this;

    var x = Math.floor(Math.random() * this.cols);
    var y = Math.floor(Math.random() * this.rows);
    var eq = x % 2;

    if (eq == 1) {
      me.drawTriangle(x * 24, Math.round((y-0.5) * 24) , this.getColor(), true);
    } else {
      me.drawTriangle(x * 24 + 2, y * 24, this.getColor());
    }

    setTimeout(function(){    
      me.animate.call(me);
    }, 10);
  },
};

!function(){livePatern.init();}()
* {
  margin: 0;
  padding: 0;
  min-height: 100%;
  width: 100%;
}

html, body {
  height: 100%;
}

canvas{
  height: 100%;
  width: 100%;
}
<canvas id="canvas"></canvas>

I want to use:

window.onresize = function() {

  ctx.clearRect(0,0,canvas.width, canvas.height);

  //call again function;
}

but animations were duplicated.

1

There are 1 best solutions below

0
On

You are setting the size of the canvas on load and save that for all the upcoming rendering. But instead you could do something like;

//pseudo code, including only the idea.
windown.onload = function () {

  var canvas = document.querySelector(...),
      context = canvas.getContext('2d');

  Dots.init();

  function prepareCanvas (w, h) {
    //set width and height
    //do more nessessary stuff
  }

  (function loop () {
    var w = window.innerWidth,
        h = window.innerHeight;

     prepareCanvas(w, h);
     Dots.render(context, w, h);


    window.requestAnimationFrame(loop);
  })();
}

So basically, add the width and height as parameters to the render method, so display size wont matter if it changes.

UPDATE, due to the comments

Cache the dimensions, than that wont happen more often than you need it.

window.onload = function () {
  var w, h, resized = true;

  window.addEventListener('resize', function () {
    resized = true;
  });

  (function loop() {
    if (resized) {
      //get w, h
      prepareCanvas(w, h);
      resized = false;
    }

     Dots.render(context, w, h);
  })();

}