<canvas id="canvas"></canvas>
html { overflow: hidden; }
// This is part of a tutorial called Canvas 101: Multiple Shapes and Reset
// URL to come soon :D
const canvas = document.querySelector("#canvas");
const context = canvas.getContext("2d");
let canvasWidth = (canvas.width = window.innerWidth);
let canvasHeight = (canvas.height = window.innerHeight);
const squares = [];
let squareCount = 50;

class Square {
  constructor({
    width,
    height,
    rotate = 0,
    xPosition = canvasWidth / 2,
    yPosition = canvasHeight / 2,
    xVelocity = 0.1
  }) {
    this.width = width;
    this.height = height;
    this.rotate = rotate;
    this.xPosition = xPosition;
    this.yPosition = yPosition;
    this.xVelocity = Math.random() * (1 - xVelocity) + xVelocity;
  }
}

for (let i = 0; i < squareCount; i++) {
  squares.push(
    new Square({
      width: 40,
      height: 40,
      xPosition:
        Math.random() * (canvasWidth * 0.9 - canvasWidth * 0.1) +
        canvasWidth * 0.1,
      yPosition:
        Math.random() * (canvasHeight * 0.9 - canvasHeight * 0.1) +
        canvasHeight * 0.1
    })
  );
}

function movement(shape) {
  if (shape.xPosition > canvasWidth + shape.width) {
    shape.xPosition = -shape.width;
  }
  shape.rotate += shape.xVelocity / 15;
  shape.xPosition += shape.xVelocity;
}

function render() {
  context.fillStyle = "lightsalmon";
  context.fillRect(0, 0, canvasWidth, canvasHeight);
  squares.forEach(square => {
    movement(square);
    context.save();
    context.fillStyle = "salmon";
    context.translate(square.xPosition, square.yPosition);
    context.rotate(square.rotate);
    context.fillRect(
      -square.width / 2,
      -square.height / 2,
      square.width,
      square.height
    );
    context.restore();
  });
  window.requestAnimationFrame(render);
}

window.requestAnimationFrame(render);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.