在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
<meta charset="UTF-8">
    <title>烟花动画</title>
    <style>
        body, html { height: 100%; margin: 0; }
        canvas { position: absolute; }
    </style>
</head>
<body>
<canvas id="fireworks"></canvas>
<audio id="background-music" loop>
    <source src="YOUR_MUSIC_FILE.mp3" type="audio/mp3">
    Your browser does not support the audio element.
</audio>
<script>
    // 获取canvas和context
    const canvas = document.getElementById('fireworks');
    const ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // Background music setup
    const backgroundMusic = document.getElementById("background-music");
    backgroundMusic.play();

    // 烟花粒子类
    class Particle {
        constructor(x, y, color, velocity, size) {
            this.x = x;
            this.y = y;
            this.color = color;
            this.velocity = velocity;
            this.size = size;
            this.alpha = 1;
            this.friction = 0.95;
            this.gravity = 0.03;
        }

        draw() {
            ctx.save();
            ctx.globalCompositeOperation = 'lighter';
            ctx.globalAlpha = this.alpha;
            ctx.fillStyle = this.color;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }

        update() {
            this.velocity.x *= this.friction;
            this.velocity.y *= this.friction;
            this.velocity.y += this.gravity;
            this.x += this.velocity.x;
            this.y += this.velocity.y;
            this.alpha -= 0.02; // fade out
        }
    }

    // 烟花类
    class Firework {
        constructor(x, y, targetY, color, size) {
            this.x = x;
            this.y = y;
            this.size = size;
            this.color = color;
            this.targetY = targetY;
            this.particles = [];
            this.exploded = false;

            // 确定烟花升空速度
            this.velocity = {
                x: 0,
                y: -Math.random() * 3 - 9
            };
        }

        // 爆炸效果
        explode() {
            // 在这里,我们可以控制烟花爆炸后的大小和样式
            for (let i = 0; i < 500; i++) {
                const angle = Math.random() * Math.PI * 2;
                const speed = Math.random() * 6 + 1;
                this.particles.push(new Particle(this.x, this.y, this.color, {
                    x: Math.cos(angle) * speed,
                    y: Math.sin(angle) * speed
                }, this.size / 2));
            }
        }

        draw() {
            if (!this.exploded) {
                ctx.save();
                ctx.globalCompositeOperation = 'lighter';
                ctx.globalAlpha = 0.8;
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            }
            for (const particle of this.particles) {
                particle.draw();
            }
        }

        update() {
            if (!this.exploded) {
                this.velocity.y += 0.1; // gravity
                this.x += this.velocity.x;
                this.y += this.velocity.y;

                // 如果达到目标高度,引发爆炸
                if (this.y < this.targetY || this.velocity.y >= 0) {
                    this.exploded = true;
                    this.explode();
                }
            }
            for (let i = this.particles.length - 1; i >= 0; i--) {
                const p = this.particles[i];
                p.update();
                if (p.alpha <= 0) {
                    this.particles.splice(i, 1);
                }
            }
        }
    }

    let fireworks = [];
    let timer = 0;

    // 生成随机颜色
    function randomColor() {
        const hue = Math.floor(Math.random() * 360);
        const saturation = 100; // 全饱和色彩
        const lightness = 60; // 正常亮度
        return `hsl(${hue},${saturation}%,${lightness}%)`;
    }

    // Text configuration
    const greetings = ['家人们,新年快乐 !','祝大家','在新的一年里 !', '身体健康 !','万事如意 !','开心快乐每一天 !'];
    let currentGreeting = 0;
    let colorHue = 0;

    function drawText() {
        ctx.font = '50px Arial';
        ctx.fillStyle = `hsl(${colorHue}, 100%, 50%)`; // HSL color value
        ctx.textAlign = 'center';
        ctx.fillText(greetings[currentGreeting], canvas.width / 2, canvas.height / 2 - 100);
    }

    // 更新动画
    function animate() {
        requestAnimationFrame(animate);
        ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        if (timer % 10 === 0) {
            const x = Math.random() * canvas.width;
            const targetY = Math.random() * (canvas.height * 0.3) + 50;
            fireworks.push(new Firework(x, canvas.height, targetY, randomColor(), Math.random() * 4 + 1));
        }
        timer++;

        for (let i = fireworks.length - 1; i >= 0; i--) {
            fireworks[i].update();
            fireworks[i].draw();
            if (fireworks[i].exploded && fireworks[i].particles.length === 0) {
                fireworks.splice(i, 1);
            }
        }
        // Update text color and content
        colorHue += 1; // Change color
        if (colorHue > 360) { colorHue = 0; } // Reset color loop
        if (timer % 300 === 0) { // Change text every few seconds
            currentGreeting = (currentGreeting + 1) % greetings.length;
        }
        // 绘制文字
        drawText();
    }

    // 适应屏幕尺寸变化
    window.addEventListener('resize', function() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    });

    animate();
</script>
</body>
</html>


     
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐