SOURCE

console 命令行工具 X clear

                    
>
console
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')

let width, height, lastNow
let snowflakes
const maxSnowflakes = 100

function init() {
  snowflakes = []
  resize()
  render(lastNow = performance.now())
}

function render(now) {
  requestAnimationFrame(render)
  
  const elapsed = now - lastNow
  lastNow = now
  
  ctx.clearRect(0, 0, width, height)
  if (snowflakes.length < maxSnowflakes)
    snowflakes.push(new Snowflake())
  
  ctx.fillStyle = ctx.strokeStyle = '#fff'

  snowflakes.forEach(snowflake => snowflake.update(elapsed, now))
}

function pause() {
  cancelAnimationFrame(render)
}
function resume() {
  lastNow = performance.now()
  requestAnimationFrame(render)
}


class Snowflake {
  constructor() {
    this.spawn()
  }
  
  spawn(anyY = false) {
    this.x = rand(0, width)
    this.y = anyY === true
      ? rand(-50, height + 50)
      : rand(-50, -10)
    this.xVel = rand(-.05, .05)
    this.yVel = rand(.02, .1)
    this.angle = rand(0, Math.PI * 2)
    this.angleVel = rand(-.001, .001)
    this.size = rand(7, 12)
    this.sizeOsc = rand(.01, .5)
  }
  
  update(elapsed, now) {
    const xForce = rand(-.001, .001);

    if (Math.abs(this.xVel + xForce) < .075) {
      this.xVel += xForce
    }
    
    this.x += this.xVel * elapsed
    this.y += this.yVel * elapsed
    this.angle += this.xVel * 0.05 * elapsed //this.angleVel * elapsed
    
    if (
      this.y - this.size > height ||
      this.x + this.size < 0 ||
      this.x - this.size > width
    ) {
      this.spawn()
    }
    
    this.render()
  }
  
  render() {
    ctx.save()
    const { x, y, angle, size } = this
    ctx.beginPath()
    ctx.arc(x, y, size * 0.2, 0, Math.PI * 2, false)
    ctx.fill()
    ctx.restore()
  }
}

// Utils
const rand = (min, max) => min + Math.random() * (max - min)

function resize() {
  width = canvas.width = window.innerWidth
  height = canvas.height = window.innerHeight
}

window.addEventListener('resize', resize)
window.addEventListener('blur', pause)
window.addEventListener('focus', resume)
init()
<canvas></canvas>
<div>
  <h1>Welcome!</h1>
  <h2>MOKUO の 小窝</h2>
  <button>MORE</button>
</div>
* {
  margin: 0;
  padding: 0;
}

div {
  width: 800px;
  height: 500px;
  background: #1686D9;
  background: linear-gradient(to right,#1686D9,#8FD3C5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  
  color: #eeeeee;
  font-family: sans-serif;
  
  h1 {
    font-size: 4em;
  }
  
  h2 {
    margin: 10px;
    font-size: 1.5em;
  }
  
  button {
    margin-top: 40px;
    width: 100px;
    height: 40px;
    background: transparent;
    border: 2px solid #eeeeee;
    color: #eeeeee;
    cursor: pointer;
    transition: border-color 400ms, color 400ms, box-shadow 400ms, transform 400ms;
    border-radius: 7px;
    outline: none;
    
    &:hover {
      border-color: white;
      color: white;
      box-shadow: 10px 15px 15px -6px #8FD3C5;
      transform: translate3d(-5px, -5px, 0);
    }
  }
}

canvas {
  position: absolute;
  width: 800px;
  height: 500px;
  background: transparent;
  pointer-events: none;
}