SOURCE

console 命令行工具 X clear

                    
>
console
/* jshint esversion: 6 */
((main) => {
	
	this.requestAnimationFrame = (() => {
		return window.requestAnimationFrame ||
			window.webkitRequestAnimationFrame ||
			window.mozRequestAnimationFrame ||
			window.oRequestAnimationFrame ||
			window.msRequestAnimationFrame ||
			function(callback) {
				window.setTimeout(callback, 1000 / 60);
			};
	})();
	
	main(this, document, Vector2);

})((window, document, v2, undefined) => {

	'use strict';
	
	const PI = Math.PI,
				TAU = PI * 2;
	
	const APP_DEFAULTS = {
		particleCount: 600,
		particleColor: 'rgba(200,200,230,0.5)'
	};
	
	class Particle{
		constructor(size, speed, context, bounds){
			this.size = size;
			this.ctx = context;
			this.bounds = bounds;
			this.position = new v2();
			this.position.randomize(bounds);
			this.velocity = new v2(0, speed);
			this.velocity.y -= Math.random();
		}
		
		reset(){
			this.position.y = this.bounds.y + this.size;
			this.position.x = Math.random() * this.bounds.x;
		}
		
		update() {
			this.position.add(this.velocity);
			if(this.position.y < -this.size){
				this.reset();
			}
		}
	}
	
	class App{
		constructor(){
			this.setup();
			this.getCanvas();
			this.resize();
			this.populate();
			this.render();
		}
		
		setup(){
			let self = this;
			self.props = Object.assign({}, APP_DEFAULTS);
			self.dimensions = new v2();
			window.onresize = () => {
				self.resize();
			};
		}
		
		getCanvas(){
			this.canvas = {
				back: document.querySelector('.back'),
				mid: document.querySelector('.mid'),
				front: document.querySelector('.front')
			};
			
			this.ctx = {
				back: this.canvas.back.getContext('2d'),
				mid: this.canvas.mid.getContext('2d'),
				front: this.canvas.front.getContext('2d')
			};
		}
		
		resize(){
			for(var c in this.canvas){
				this.canvas[c].width = this.dimensions.x = window.innerWidth;
				this.canvas[c].height = this.dimensions.y = window.innerHeight;
			}
		}
		
		populate(){
			this.particles = [];
			for(let i = 0; i < this.props.particleCount; i++){
				let pCtx = i < 300 ? this.ctx.back : i < 500 ? this.ctx.mid : this.ctx.front,
					size = i < 300 ? 5 : i < 500 ? 8 : 12,
					speed = i < 300 ? -0.5 : i < 500 ? -1 : -2,
					particle = new Particle(size, speed, pCtx, this.dimensions);
				this.particles.push(particle);
			}
		}
		
		render() {
			let self = this;
			self.draw();
			window.requestAnimationFrame(self.render.bind(self));
		}
		
		draw() {
			for(var c in this.ctx){
				this.ctx[c].clearRect(0,0,this.dimensions.x, this.dimensions.y);
			}
			for(let i = 0, len = this.particles.length; i < len; i++){
				let p = this.particles[i];
				p.update();
				p.ctx.beginPath();
				p.ctx.fillStyle = this.props.particleColor;
				p.ctx.arc(p.position.x, p.position.y, p.size, 0, TAU);
				p.ctx.fill();
				p.ctx.closePath();
			}
		}
	}
	
	window.onload = () => {
		let app = new App();
	};
	
});
<canvas class="back"></canvas>
<canvas class="mid"></canvas>
<canvas class="front"></canvas>
body {
  background: #000000;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
  height: 100vh;
  width: 100vw;
}

.back {
  z-index: 0;
  -webkit-filter: blur(6px);
          filter: blur(6px);
  background-image: -webkit-radial-gradient(#4682b4, #191970);
  background-image: radial-gradient(#4682b4, #191970);
}

.mid {
  z-index: 1;
  -webkit-filter: blur(3px);
          filter: blur(3px);
  mix-blend-mode: lighten;
  background: rgba(20, 20, 20, 0.5);
}

.front {
  z-index: 2;
  -webkit-filter: blur(1px);
          filter: blur(1px);
  mix-blend-mode: luminosity;
}

本项目引用的自定义外部资源