SOURCE

console 命令行工具 X clear

                    
>
console
// Learn to code this at:
// https://www.youtube.com/watch?v=3b7FyIxWW94

// Initial Setup
var canvas = document.querySelector('canvas');
var c = canvas.getContext('2d');

canvas.width = innerWidth;
canvas.height = innerHeight;


// Variables
var mouse = {
	x: innerWidth / 2,
	y: innerHeight / 2 
};

var colors = [
	'#2185C5',
	'#7ECEFD',
	'#FFF6E5',
	'#FF7F66'
];

var gravity = 0.2;
var friction = 0.98;


// Event Listeners
addEventListener("mousemove", function(event) {
	mouse.x = event.clientX;
	mouse.y = event.clientY;
});

addEventListener("resize", function() {
	canvas.width = innerWidth;	
	canvas.height = innerHeight;
  init();
});

addEventListener("click", function(event) {
	init();
});


// Utility Functions
function randomIntFromRange(min,max) {
	return Math.floor(Math.random() * (max - min + 1) + min);
}

function randomColor(colors) {
	return colors[Math.floor(Math.random() * colors.length)];
}


// Objects
function Ball(x, y, dx, dy, radius, color) {
	this.x = x;
	this.y = y;
	this.dx = dx;
	this.dy = dy;
	this.radius = radius;
	this.color = color;

	this.update = function() {
		if (this.y + this.radius + this.dy> canvas.height) {
			this.dy = -this.dy;
			this.dy = this.dy * friction;
			this.dx = this.dx * friction;
		} else {
			this.dy += gravity;
		}

		if (this.x + this.radius >= canvas.width || this.x - this.radius <= 0) {
			this.dx = -this.dx * friction;
		}

		this.x += this.dx;
		this.y += this.dy;
		this.draw();
	};

	this.draw = function() {
		c.beginPath();
		c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);	
		c.fillStyle = this.color;
		c.fill();
		c.stroke();
		c.closePath();
	};
}


// Implementation
var ballArray = [];

function init() {
	ballArray = [];

	for (let i = 0; i < 600; i++) {
		var radius = randomIntFromRange(8, 20);
		var x = randomIntFromRange(radius, canvas.width - radius);
		var y = randomIntFromRange(0, canvas.height - radius);
		var dx = randomIntFromRange(-3, 3)
		var dy = randomIntFromRange(-2, 2)
	    ballArray.push(new Ball(x, y, dx, dy, radius, randomColor(colors)));
	}
}

// Animation Loop
function animate() {
	requestAnimationFrame(animate);

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

	for (let i = 0; i < ballArray.length; i++) {
		ballArray[i].update();
	}
}

init();
animate();
<canvas></canvas>
<p>Click to Restart Simulation</p>

<!-- Social -->
<div class="twitter social-icon">
  <a href="https://twitter.com/christopher4lis" target="_blank"></a>
  <i class="fa fa-twitter fa-lg"></i>
</div>

<div class="youtube social-icon">
  <a href="https://www.youtube.com/c/chriscourses" target="_blank"></a>
  <i class="fa fa-youtube fa-lg"></i>
</div>
body {
  margin: 0;
  overflow: hidden;
}

p {
  color: #333;
  position: absolute;
  top: 0px;
  left: 20px;
  font-family: 'Open Sans', sans-serif;
}

// Twitter
.twitter {
  &:hover {
    a {
      transform: rotate(-45deg) scale(1.05);
    }
    
    i {
      color: lighten(#00ACED, 10%);
    }
  }
  
  a {
    bottom: -40px;
    right: -75px;
    transform: rotate(-45deg);
  }
  
  i {
    bottom: 7px;
    right: 7px;
    color: #00ACED;
  }
}

.social-icon {
  a {
    position: absolute;
    background: white;
    color: white;
    box-shadow: -1px -1px 20px 0px rgba(0,0,0,0.30);
    display: inline-block;
    width: 150px;
    height: 80px;  
    transform-origin: 50% 50%;
    transition: .15s ease-out;
  }
  
  i {
    position: absolute;
    pointer-events: none;
    z-index: 1000;
    transition: .15s ease-out;
  }
}

// YouTube 

.youtube {
  &:hover {
    a {
      transform: rotate(45deg) scale(1.05);
    }
    
    i {
      color: lighten(#E62117, 10%);
    }
  }
  
  a {
    bottom: -40px;
    left: -75px;
    transform: rotate(45deg);
  }
  
  i {
    bottom: 7px;
    left: 7px;
    color: #E62117;
  }
}