HTML实现流星雨

代码文件:「基于html实现流星+星辰」,链接:https://pan.quark.cn/s/59679c01ebc5

整体结构

该项目采用简洁的单文件结构,主要由三部分组成:

  1. HTML 结构:定义基础页面和 Canvas 元素
  2. CSS 样式:设置全屏黑色背景和 Canvas 布局
  3. JavaScript 逻辑:实现星星背景、流星生成和动画效果

核心功能实现

1. Canvas 初始化

javascript 复制代码
const canvas = document.getElementById('meteorCanvas');
const ctx = canvas.getContext('2d');

function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

resizeCanvas();
window.addEventListener('resize', resizeCanvas);

这段代码首先获取 Canvas 元素及其 2D 渲染上下文,然后定义了 resizeCanvas() 函数来确保 Canvas 尺寸与窗口同步,并添加窗口大小改变事件监听器以实现响应式效果。

2. 星空背景实现

javascript 复制代码
const stars = [];
const starCount = 500;

function initStars() {
    stars.length = 0;
    for (let i = 0; i < starCount; i++) {
        stars.push({
            x: Math.random() * canvas.width,
            y: Math.random() * canvas.height,
            size: Math.random() * 2 + 0.5,
            opacity: Math.random() * 0.7 + 0.3,
            twinkleSpeed: Math.random() * 0.02 + 0.005,
            twinkleDirection: 1
        });
    }
}

初始化函数 initStars() 创建了 500 个随机分布的星星,每个星星都有独立的位置、大小、透明度和闪烁参数,为后续实现闪烁效果奠定基础。

3. 流星生成机制

javascript 复制代码
const meteors = [];

function createMeteor() {
    const angle = Math.PI / 4; // 45度角
    
    // 随机起始位置:左侧或上方
    let startX, startY;
    if (Math.random() > 0.5) {
        startX = Math.random() * -100;
        startY = Math.random() * canvas.height * 0.7;
    } else {
        startX = Math.random() * canvas.width * 0.7;
        startY = Math.random() * -100;
    }
    
    // 计算结束位置
    const flightDistance = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height) * 1.5;
    const endX = startX + Math.cos(angle) * flightDistance;
    const endY = startY + Math.sin(angle) * flightDistance;
    
    // 流星属性
    meteors.push({
        x: startX,
        y: startY,
        endX: endX,
        endY: endY,
        length: Math.random() * 70 + 80,
        width: Math.random() * 1 + 1,
        speed: Math.random() * 10 + 5,
        progress: 0,
        alpha: 1,
        color: getRandomMeteorColor()
    });
}

流星生成函数是实现流星雨效果的核心。它通过以下机制工作:

  • 设置固定的 45 度角,确保所有流星保持统一的飞行方向
  • 随机选择起始位置(屏幕左侧或上方)
  • 根据固定角度和飞行距离计算结束位置,确保流星能够完整划过屏幕
  • 为每个流星设置随机的长度、宽度、速度等属性,增加视觉变化

4. 流星颜色系统

javascript 复制代码
function getRandomMeteorColor() {
    const colors = [
        'rgba(255, 255, 255, ',  // 纯白色
        'rgba(255, 248, 225, ',  // 米白色
        'rgba(255, 250, 240, ',  // 淡雪青色
        'rgba(255, 255, 240, '   // 象牙白
    ];
    return colors[Math.floor(Math.random() * colors.length)];
}

该函数返回四种白亮色中的一种,确保流星在黑色背景上具有良好的可见性,同时保持流星雨的自然美感。

5. 渲染函数实现

5.1 星星渲染与闪烁效果
javascript 复制代码
function drawStars() {
    ctx.fillStyle = 'white';
    stars.forEach(star => {
        // 实现星星闪烁效果
        star.opacity += star.twinkleSpeed * star.twinkleDirection;
        if (star.opacity > 1 || star.opacity < 0.3) {
            star.twinkleDirection *= -1;
        }
        
        ctx.globalAlpha = star.opacity;
        ctx.fillRect(star.x, star.y, star.size, star.size);
    });
    ctx.globalAlpha = 1;
}

drawStars() 函数不仅绘制星星,还实现了星星的闪烁效果。通过不断调整每个星星的透明度,并在达到阈值时反转变化方向,创造出星星忽明忽暗的动态效果。

5.2 流星渲染与轨迹效果
javascript 复制代码
function drawMeteors() {
    meteors.forEach((meteor, index) => {
        // 更新流星位置
        meteor.progress += meteor.speed / (
            Math.sqrt(
                Math.pow(meteor.endX - meteor.x, 2) + 
                Math.pow(meteor.endY - meteor.y, 2)
            )
        );
        
        // 计算当前位置
        const currentX = meteor.x + (meteor.endX - meteor.x) * meteor.progress;
        const currentY = meteor.y + (meteor.endY - meteor.y) * meteor.progress;
        
        // 透明度随进度变化
        meteor.alpha = 1 - meteor.progress;
        ctx.globalAlpha = meteor.alpha;
        
        // 绘制流星轨迹
        const angle = Math.atan2(meteor.endY - meteor.y, meteor.endX - meteor.x);
        const trailX = currentX - Math.cos(angle) * meteor.length;
        const trailY = currentY - Math.sin(angle) * meteor.length;
        
        // 创建渐变效果
        const gradient = ctx.createLinearGradient(trailX, trailY, currentX, currentY);
        gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
        gradient.addColorStop(0.5, meteor.color + (meteor.alpha * 0.8) + ')');
        gradient.addColorStop(1, meteor.color + (meteor.alpha * 1.5) + ')');
        
        // 绘制流星主体
        ctx.strokeStyle = gradient;
        ctx.lineWidth = meteor.width;
        ctx.lineCap = 'round';
        ctx.beginPath();
        ctx.moveTo(trailX, trailY);
        ctx.lineTo(currentX, currentY);
        ctx.stroke();
        
        // 绘制流星头部光晕
        ctx.beginPath();
        ctx.arc(currentX, currentY, meteor.width * 2.5, 0, Math.PI * 2);
        ctx.fillStyle = meteor.color + (meteor.alpha * 1.0) + ')';
        ctx.fill();
        
        // 移除已完成的流星
        if (meteor.progress >= 1) {
            meteors.splice(index, 1);
        }
    });
    ctx.globalAlpha = 1;
}

drawMeteors() 函数是渲染逻辑中最复杂的部分,它实现了:

  • 基于进度的位置更新算法
  • 透明度随进度的自然衰减
  • 使用线性渐变创建流星的轨迹效果
  • 在流星头部添加光晕效果,增强视觉冲击力
  • 自动移除已完成飞行的流星,避免内存泄漏

6. 动画循环与定时生成

javascript 复制代码
function animate() {
    // 清空画布
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    
    // 绘制星星
    drawStars();
    
    // 绘制流星
    drawMeteors();
    
    // 请求下一帧
    requestAnimationFrame(animate);
}

function scheduleMeteors() {
    // 批量生成流星
    const meteorBatchCount = Math.floor(Math.random() * 4) + 3; // 3-6个/批
    for (let i = 0; i < meteorBatchCount; i++) {
        createMeteor();
    }
    // 设置随机间隔
    const next = Math.random() * 300 + 50; // 50-300毫秒
    setTimeout(scheduleMeteors, next);
}
  • animate() 函数使用 requestAnimationFrame() 创建流畅的动画循环,每帧清空画布并重新渲染所有元素
  • scheduleMeteors() 函数实现了流星雨的密集效果,每批生成 3-6 个流星,并在 50-300 毫秒的随机间隔后生成下一批

7. 程序初始化

javascript 复制代码
// 初始化并启动动画
initStars();
scheduleMeteors();
animate();

最后,程序通过简单的三行代码启动:初始化星星背景、开始定时生成流星、启动动画循环。

相关推荐
黄筱筱筱筱筱筱筱2 分钟前
7.适合新手小白学习Python的异常处理(Exception)
java·前端·数据库·python
Yeats_Liao9 分钟前
微调决策树:何时使用Prompt Engineering,何时选择Fine-tuning?
前端·人工智能·深度学习·算法·决策树·机器学习·prompt
晚霞的不甘9 分钟前
Flutter for OpenHarmony 实现 iOS 风格科学计算器:从 UI 到表达式求值的完整解析
前端·flutter·ui·ios·前端框架·交互
陈希瑞12 分钟前
OpenClaw Chrome扩展使用教程 - 浏览器中继控制
前端·chrome
雨季66617 分钟前
Flutter 三端应用实战:OpenHarmony “呼吸灯”——在焦虑时代守护每一次呼吸的数字禅修
开发语言·前端·flutter·ui·交互
切糕师学AI18 分钟前
Vue 中如何修改地址栏参数并重新加载?
前端·javascript·vue.js
软弹18 分钟前
Vue3如何融合TS
前端·javascript·vue.js
0思必得08 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5169 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino9 小时前
图片、文件的预览
前端·javascript