2023-10-23 01:17:33 +08:00
|
|
|
// 清理默认样式
|
|
|
|
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 = []
|
2023-10-23 02:22:06 +08:00
|
|
|
const particleCount = 100
|
2023-10-23 01:17:33 +08:00
|
|
|
|
|
|
|
// 生成粒子
|
|
|
|
for (let i = 0; i < particleCount; i++) {
|
2023-10-23 01:49:34 +08:00
|
|
|
const quality = Math.random() * 0.5 + 0.5
|
2023-10-23 01:17:33 +08:00
|
|
|
particles.push({
|
2023-10-23 02:22:06 +08:00
|
|
|
x: Math.random() * width, // 粒子的位置
|
|
|
|
y: Math.random() * height, // 粒子的位置
|
|
|
|
vx: 0, // 粒子的速度
|
|
|
|
vy: 0, // 粒子的速度
|
|
|
|
radius: Math.random() * 1 + 1, // 粒子的大小
|
|
|
|
quality, // 粒子的质量
|
2023-10-23 01:49:34 +08:00
|
|
|
color: `rgb(${Math.floor(255 * (1 - quality))}, ${Math.floor(255 * (1 - quality))}, ${Math.floor(255 * (1 - quality))})` // 粒子的颜色(质量越大,颜色越深)
|
2023-10-23 01:17:33 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 绘制粒子
|
|
|
|
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)
|
2023-10-23 01:49:34 +08:00
|
|
|
ctx.fillStyle = particle.color
|
2023-10-23 01:17:33 +08:00
|
|
|
ctx.fill()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 将粒子的位置更新到下一帧
|
|
|
|
function updateParticles () {
|
|
|
|
for (let i = 0; i < particleCount; i++) {
|
|
|
|
const particle = particles[i]
|
2023-10-23 01:49:34 +08:00
|
|
|
|
2023-10-23 02:22:06 +08:00
|
|
|
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.x += particle.vx * 1000
|
|
|
|
particle.y += particle.vy * 1000
|
|
|
|
|
|
|
|
// 只打印第一个粒子的速度
|
|
|
|
if (i === 0) {
|
|
|
|
console.log(particle.vx, particle.vy)
|
|
|
|
}
|
2023-10-23 01:17:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 清空画布
|
|
|
|
function clear () {
|
|
|
|
ctx.clearRect(0, 0, width, height)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 绘制
|
|
|
|
function draw () {
|
|
|
|
clear()
|
|
|
|
drawParticles()
|
|
|
|
updateParticles()
|
|
|
|
requestAnimationFrame(draw)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 开始绘制
|
|
|
|
draw()
|