实现步骤:
Canvas 设置和样式:
- 使用
<canvas>
元素创建一个全屏的画布,用于绘制流星。Meteor 类:
- 定义了一个
Meteor
类来表示流星,每个流星有起始位置 (x, y
)、长度 (length
)、速度 (speed
) 和颜色 (color
)。随机生成流星:
initMeteors(numMeteors)
函数用于初始化指定数量的流星,每颗流星的位置、长度、速度和颜色都是随机生成的。动画循环:
animateMeteors()
函数是主要的动画循环,每帧更新每颗流星的位置并重新绘制。如果流星移出屏幕,则重新设置其起始位置,实现流星穿越的效果。响应式处理:
- 在窗口大小改变时,重新设置 Canvas 的大小,并重新生成流星,确保它们适应新的尺寸。
效果图:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="meteorCanvas"></canvas>
</body>
<script>
const canvas = document.getElementById("meteorCanvas");
const ctx = canvas.getContext("2d");
const width = (canvas.width = window.innerWidth);
const height = (canvas.height = window.innerHeight);
// 保存所有流星
let meteors = [];
// 用于生成范围内的随机整数
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// 流星类
class Meteor {
constructor(x, y, length, speed, color) {
this.x = x;
this.y = y;
this.length = length;
this.speed = speed;
this.color = color;
}
// 更新流星的位置
update() {
this.x -= this.speed;
this.y += this.speed;
}
// 绘制流星
draw() {
ctx.save();
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x + this.length, this.y - this.length);
ctx.strokeStyle = this.color;
ctx.lineWidth = 2;
ctx.stroke();
ctx.closePath();
ctx.restore();
}
}
// 初始化流星
function initMeteors(numMeteors) {
for (let i = 0; i < numMeteors; i++) {
const x = randomInt(0, width);
const y = randomInt(-height, 0);
const length = randomInt(10, 30);
const speed = randomInt(5, 15);
const color = `rgba(255, 255, 255, ${Math.random()})`; // Random opacity
meteors.push(new Meteor(x, y, length, speed, color));
}
}
// 动画循环
function animateMeteors() {
ctx.clearRect(0, 0, width, height);
for (let i = 0; i < meteors.length; i++) {
meteors[i].update();
meteors[i].draw();
// 如果离开屏幕重置流星
if (
meteors[i].x + meteors[i].length < 0 ||
meteors[i].y - meteors[i].length > height
) {
meteors[i].x = randomInt(0, width);
meteors[i].y = randomInt(-height, 0);
}
}
requestAnimationFrame(animateMeteors);
}
// 初始化流星并开始动画
initMeteors(100); // 流星数目
animateMeteors();
// 监听窗口大小变化,重新设置canvas大小
window.addEventListener("resize", function () {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
meteors = []; // 重置流星数
initMeteors(20); // 重新初始化流星
});
</script>
</html>