canvas
View Compiled
*
  box-sizing border-box

canvas
  height 100vh
  width 100vw
  position fixed
  top 0
  right 0
  bottom 0
  left 0

body
  min-height 100vh
  background hsl(0, 0%, 10%)
View Compiled
// Let's make something cool!
const {
  _: { debounce },
  Matter: { Body, Render, Engine, World, Bodies, Events },
  gsap: {
    utils: { random },
    to,
  },
} = window
// eslint-disable-next-line
console.clear()

const ORIGINAL_SIZE = 76
const TEXTURES = [
  'https://assets.codepen.io/605876/bear--default-badge-large.png',
  'https://assets.codepen.io/605876/bear--gold-badge--large.png',
  'https://assets.codepen.io/605876/bear--silver-badge--large.png',
  'https://assets.codepen.io/605876/bear-bronze-badge-large.png',
  'https://assets.codepen.io/605876/bear-emerald-badge-large.png',
  'https://assets.codepen.io/605876/bear-purple-badge-large.png',
]

const canvas = document.querySelector('canvas')

const engine = Engine.create({
  enableSleeping: true,
})

const render = Render.create({
  element: document.body,
  canvas,
  engine: engine,
  options: {
    background: 'transparent',
    wireframeBackground: 'transparent',
    wireframes: false,
    width: window.innerWidth,
    height: window.innerHeight,
  },
})

// Create the ground
const ground = Bodies.rectangle(0, window.innerHeight - 10, 10000, 1, {
  isStatic: true,
  render: {
    opacity: 0,
  },
})

// add all of the bodies to the world
World.add(engine.world, [ground])

// run the engine
Engine.run(engine)

// run the renderer
Render.run(render)

const addBear = () => {
  const HEADS = []
  const amount = 100
  for (let h = 0; h < amount; h++) {
    const SIZE = random(25, 76)
    const HEAD = Bodies.rectangle(
      random(0, window.innerWidth),
      -100,
      SIZE,
      SIZE,
      {
        angle: random(0, 360) * (Math.PI / 180),
        render: {
          strokeStyle: '#ffffff',
          sprite: {
            texture:
              TEXTURES[Math.floor(random(0, TEXTURES.length))],
            xScale: SIZE / ORIGINAL_SIZE,
            yScale: SIZE / ORIGINAL_SIZE,
          },
        },
      }
    )
    if (Math.random() > 0.5)
      to(HEAD, {
        angle: `${Math.random() > 0.5 ? '-' : '+'}=${(360 * Math.PI) / 180}`,
        repeat: -1,
        duration: random(0.2, 2),
      })
    Events.on(HEAD, 'sleepStart', () => {
      World.remove(engine.world, HEAD)
      if (engine.world.bodies.length < 80) mixed()
    })
    HEADS.push(HEAD)
  }
  World.add(engine.world, HEADS)
}

const mixed = () => addBear()
const bear = () => addBear(0)
const golden = () => addBear(1)
const silver = () => addBear(2)
const bronze = () => addBear(3)
const green = () => addBear(4)
const purpleRain = () => addBear(5)
const clear = () => World.clear(engine.world, true)

document.body.addEventListener('click', mixed)
window.addEventListener(
  'resize',
  debounce(() => {
    World.clear(engine.world, true)
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    Body.setPosition(ground, {
      x: 0,
      y: window.innerHeight - 10,
    })
    mixed()
  }, 500)
)

mixed()
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.3/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js