distributed/main.js

100 lines
3.0 KiB
JavaScript

// 清理默认样式
document.body.style.margin = 0
document.body.style.padding = 0
document.body.style.overflow = 'hidden'
// 创建一个画布
const canvas = document.createElement('canvas')
document.body.appendChild(canvas)
// 画布填满屏幕
const ctx = canvas.getContext('2d')
const width = canvas.width = window.innerWidth
const height = canvas.height = window.innerHeight
// 画布中心点
const centerX = width / 2
const centerY = height / 2
// 画布中心点的偏移量
const offsetX = 0
const offsetY = 0
// 准备一千个小圆点作为粒子
const particles = []
const particleCount = 100
// 生成粒子
for (let i = 0; i < particleCount; i++) {
const quality = Math.random() * 0.5 + 0.5
particles.push({
x: Math.random() * width, // 粒子的位置
y: Math.random() * height, // 粒子的位置
vx: 0, // 粒子的速度
vy: 0, // 粒子的速度
radius: Math.random() * 1 + 1, // 粒子的大小
quality, // 粒子的质量
color: `rgb(${Math.floor(255 * (1 - quality))}, ${Math.floor(255 * (1 - quality))}, ${Math.floor(255 * (1 - quality))})` // 粒子的颜色(质量越大,颜色越深)
})
}
// 绘制粒子
function drawParticles () {
for (let i = 0; i < particleCount; i++) {
const particle = particles[i]
ctx.beginPath()
ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2)
ctx.fillStyle = particle.color
ctx.fill()
}
}
// 将粒子的位置更新到下一帧
function updateParticles () {
for (let i = 0; i < particleCount; i++) {
const particle = particles[i]
particle.vx = 0
particle.vy = 0
// 粒子与其他每个粒子在坐标轴上的距离, 最近距离引力为1, 距离每增加1则引力减少1/2
for (let j = 0; j < particleCount; j++) {
if (i === j) {
continue
}
const other = particles[j] // 其他粒子
const dx = particle.x - other.x // 粒子与其他粒子在x轴上的距离
const dy = particle.y - other.y // 粒子与其他粒子在y轴上的距离
const distance = Math.sqrt(dx * dx + dy * dy) // 粒子与其他粒子在坐标轴上的距离
const forceValue = 1 / (distance * distance) // 粒子与其他粒子的引力
const forceAngle = Math.atan2(dy, dx) // 粒子与其他粒子的引力角度
particle.vx += forceValue * Math.cos(forceAngle) // 粒子在x轴上的速度
particle.vy += forceValue * Math.sin(forceAngle) // 粒子在y轴上的速度
}
// 引力取反
particle.vx *= -1
particle.vy *= -1
// 模拟引力
particle.x += particle.vx * 10000 // 快进 10000 倍
particle.y += particle.vy * 10000 // 快进 10000 倍
}
}
// 清空画布
function clear () {
ctx.clearRect(0, 0, width, height)
}
// 绘制
function draw () {
clear()
drawParticles()
updateParticles()
requestAnimationFrame(draw)
}
// 开始绘制
draw()