HTML5 and JS realize New Year fireworks effect

HTML5 and JS realize New Year fireworks effect

Goodbye in 2023, the Year of the Rabbit, and 2024, the Year of the Dragon is here!

I wish readers and friends good health, happy souls and dreams come true in 2024.

The following is the use of HTML5 and JS to achieve the New Year fireworks effect:

The source code is as follows:

<!DOCTYPE html>
<html>
<head>
    <title>新年礼花</title>
    <style>
        /* 设置画布占满整个窗口 */
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <!-- 创建一个画布 -->
    <canvas id="fireworksCanvas"></canvas>

    <script>
        // 获取canvas和context
        const canvas = document.getElementById('fireworksCanvas');
        const ctx = canvas.getContext('2d');
        // 设置canvas宽高为窗口的宽高
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        // 初始化烟花数组
        let fireworks = [];

        // 定义产生min到max之间的随机数的函数
        function random(min, max) {
            return Math.random() * (max - min) + min;
        }

        // 定义烟花类
        class Firework {
            constructor(x, y, color) {
                this.x = x;
                this.y = y;
                this.particles = [];
                this.exploded = false;
                this.life = 0;
                this.color = color;
                this.explodeHeight = random(canvas.height * 0.3, canvas.height * 0.6);
            }

            // 更新烟花状态的方法
            update() {
                // 如果烟花还未爆炸,向上移动,并增加寿命
                if (!this.exploded) {
                    this.y -= random(5, 10);
                    this.life += 1;
                    // 如果烟花达到或超过爆炸高度,爆炸
                    if (this.y <= this.explodeHeight) {
                        this.explode();
                    }
                } else {
                    // 如果烟花已经爆炸,更新和绘制粒子
                    this.particles.forEach((particle, index) => {
                        particle.update();
                        if (particle.life < 0) {
                            this.particles.splice(index, 1);
                        }
                    });
                }
            }

            // 绘制烟花的方法
            draw() {
                if (!this.exploded) {
                    ctx.fillStyle = this.color;
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
                    ctx.fill();
                } else {
                    this.particles.forEach((particle) => particle.draw());
                }
            }

            // 烟花爆炸的方法
            explode() {
                this.exploded = true;
                for (let i = 0; i < 100; i++) {
                    const angle = random(0, Math.PI * 2);
                    const speed = random(1, 4);
                    this.particles.push(new Particle(this.x, this.y, angle, speed, this.color));
                }
            }
        }

        // 定义粒子类
        class Particle {
            constructor(x, y, angle, speed, color) {
                this.x = x;
                this.y = y;
                this.angle = angle;
                this.speed = speed;
                this.life = random(50, 100);
                this.color = color;
            }

            // 更新粒子状态的方法
            update() {
                this.x += Math.cos(this.angle) * this.speed;
                this.y += Math.sin(this.angle) * this.speed;
                this.speed *= 0.99;
                this.life -= 1;
            }

            // 绘制粒子的方法
            draw() {
                ctx.fillStyle = this.color + ', ' + (this.life / 100) + ')';
                ctx.beginPath();
                ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
                ctx.fill();
            }
        }

        // 动画函数
        function animate() {
            // 绘制背景
            ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // 以5%的概率添加新烟花
            if (Math.random() < 0.05) {
                const x = random(0, canvas.width);
                const y = canvas.height;
                const fireworkColor = 'hsla(' + random(0, 360) + ', 100%, 50%';
                fireworks.push(new Firework(x, y, fireworkColor));
            }

            // 更新和绘制烟花
            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);
                }
            }

            // 显示文字
            ctx.font = "50px Arial";
            ctx.fillStyle = "pink";
            ctx.textAlign = "center";
            ctx.fillText("2024年龙年快乐", canvas.width / 2, canvas.height / 2);
            
            // 继续下一帧动画
            requestAnimationFrame(animate);
        }

        // 启动动画
        animate();

        // 监听窗口大小变化,重新设置画布大小
        window.addEventListener('resize', function() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });

    </script>
</body>
</html>

Modification 1 : Add New Year's greetings and make the text scroll from the center to the bottom. The effect is as follows:

The source code is as follows:

<!DOCTYPE html>
<html>
<head>
<title>新年礼花</title>
<style>
/* 设置画布占满整个窗口 */
body {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
display: block;
}
.scrolling-text {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
text-align: center;
color: red;
animation: scrollText 10s linear infinite;
}

    @keyframes scrollText {
        0% {
            top: 100%;
        }
        100% {
            top: -100%;
        }
    }
</style>
</head>
<body>
<!-- 创建一个画布 -->
<canvas id="fireworksCanvas"></canvas>
<div class="scrolling-text">
<p>《元日》</p>
<p>宋·王安石</p>
<p>爆竹声中一岁除,</p>
<p>春风送暖入屠苏。</p>
<p>千门万户曈曈日,</p>
<p>总把新桃换旧符。</p>
</div>

<script>
    // 获取canvas和context
    const canvas = document.getElementById('fireworksCanvas');
    const ctx = canvas.getContext('2d');
    // 设置canvas宽高为窗口的宽高
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    // 初始化烟花数组
    let fireworks = [];

    // 定义产生min到max之间的随机数的函数
    function random(min, max) {
        return Math.random() * (max - min) + min;
    }

    // 定义烟花类
    class Firework {
        constructor(x, y, color) {
            this.x = x;
            this.y = y;
            this.particles = [];
            this.exploded = false;
            this.life = 0;
            this.color = color;
            this.explodeHeight = random(canvas.height * 0.3, canvas.height * 0.6);
        }

        // 更新烟花状态的方法
        update() {
            // 如果烟花还未爆炸,向上移动,并增加寿命
            if (!this.exploded) {
                this.y -= random(5, 10);
                this.life += 1;
                // 如果烟花达到或超过爆炸高度,爆炸
                if (this.y <= this.explodeHeight) {
                    this.explode();
                }
            } else {
                // 如果烟花已经爆炸,更新和绘制粒子
                this.particles.forEach((particle, index) => {
                    particle.update();
                    if (particle.life < 0) {
                        this.particles.splice(index, 1);
                    }
                });
            }
        }

        // 绘制烟花的方法
        draw() {
            if (!this.exploded) {
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
                ctx.fill();
            } else {
                this.particles.forEach((particle) => particle.draw());
            }
        }

        // 烟花爆炸的方法
        explode() {
            this.exploded = true;
            for (let i = 0; i < 100; i++) {
                const angle = random(0, Math.PI * 2);
                const speed = random(1, 4);
                this.particles.push(new Particle(this.x, this.y, angle, speed, this.color));
            }
        }
    }

    // 定义粒子类
    class Particle {
        constructor(x, y, angle, speed, color) {
            this.x = x;
            this.y = y;
            this.angle = angle;
            this.speed = speed;
            this.life = random(50, 100);
            this.color = color;
        }

        // 更新粒子状态的方法
        update() {
            this.x += Math.cos(this.angle) * this.speed;
            this.y += Math.sin(this.angle) * this.speed;
            this.speed *= 0.99;
            this.life -= 1;
        }

        // 绘制粒子的方法
        draw() {
            ctx.fillStyle = this.color + ', ' + (this.life / 100) + ')';
            ctx.beginPath();
            ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
            ctx.fill();
        }
    }

    // 动画函数
    function animate() {
        // 绘制背景
        ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // 以5%的概率添加新烟花
        if (Math.random() < 0.05) {
            const x = random(0, canvas.width);
            const y = canvas.height;
            const fireworkColor = 'hsla(' + random(0, 360) + ', 100%, 50%';
            fireworks.push(new Firework(x, y, fireworkColor));
        }

        // 更新和绘制烟花
        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);
            }
        }

        // 显示文字
        ctx.font = "50px Arial";
        ctx.fillStyle = "pink";
        ctx.textAlign = "center";
        ctx.fillText("2024年龙年快乐", canvas.width / 2, canvas.height / 2);

        // 继续下一帧动画
        requestAnimationFrame(animate);
    }

    // 启动动画
    animate();

    // 监听窗口大小变化,重新设置画布大小
    window.addEventListener('resize', function() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    });

</script>
</body>
</html>

Modification 2 : Add background music, making sure to place the music file (I named it "background_music.mp3" here) in the same directory as the HTML file. The music control buttons should now appear in the upper left corner. The effect is as follows:

The source code is as follows:

<!DOCTYPE html>
<html>
<head>
    <title>新年礼花</title>
    <style>
        /* 设置画布占满整个窗口 */
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
        .scrolling-text {
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            font-size: 24px;
            text-align: center;
            color: red;
            animation: scrollText 10s linear infinite;
        }
        
        @keyframes scrollText {
            0% {
                top: 100%;
            }
            100% {
                top: -100%;
            }
        }
        .button-container {
            position: absolute;
            top: 10px;
            left: 10px;
        }
        .button-container button {
            padding: 10px 20px;
            font-size: 16px;
        }
    </style>
</head>
<body>
    <!-- 创建一个画布 -->
    <canvas id="fireworksCanvas"></canvas>
    <div class="scrolling-text">
        <p>《元日》</p>
        <p>宋·王安石</p>
        <p>爆竹声中一岁除,</p>
        <p>春风送暖入屠苏。</p>
        <p>千门万户曈曈日,</p>
        <p>总把新桃换旧符。</p>
    </div>
    <div class="button-container">
        <button id="playButton">播放音乐</button>
    </div>
 
    <script>
        // 获取canvas和context
        const canvas = document.getElementById('fireworksCanvas');
        const ctx = canvas.getContext('2d');
        // 设置canvas宽高为窗口的宽高
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        // 初始化烟花数组
        let fireworks = [];
 
        // 定义产生min到max之间的随机数的函数
        function random(min, max) {
            return Math.random() * (max - min) + min;
        }
 
        // 定义烟花类
        class Firework {
            constructor(x, y, color) {
                this.x = x;
                this.y = y;
                this.particles = [];
                this.exploded = false;
                this.life = 0;
                this.color = color;
                this.explodeHeight = random(canvas.height * 0.3, canvas.height * 0.6);
            }
 
            // 更新烟花状态的方法
            update() {
                // 如果烟花还未爆炸,向上移动,并增加寿命
                if (!this.exploded) {
                    this.y -= random(5, 10);
                    this.life += 1;
                    // 如果烟花达到或超过爆炸高度,爆炸
                    if (this.y <= this.explodeHeight) {
                        this.explode();
                    }
                } else {
                    // 如果烟花已经爆炸,更新和绘制粒子
                    this.particles.forEach((particle, index) => {
                        particle.update();
                        if (particle.life < 0) {
                            this.particles.splice(index, 1);
                        }
                    });
                }
            }
 
            // 绘制烟花的方法
            draw() {
                if (!this.exploded) {
                    ctx.fillStyle = this.color;
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
                    ctx.fill();
                } else {
                    this.particles.forEach((particle) => particle.draw());
                }
            }
 
            // 烟花爆炸的方法
            explode() {
                this.exploded = true;
                for (let i = 0; i < 100; i++) {
                    const angle = random(0, Math.PI * 2);
                    const speed = random(1, 4);
                    this.particles.push(new Particle(this.x, this.y, angle, speed, this.color));
                }
            }
        }
 
        // 定义粒子类
        class Particle {
            constructor(x, y, angle, speed, color) {
                this.x = x;
                this.y = y;
                this.angle = angle;
                this.speed = speed;
                this.life = random(50, 100);
                this.color = color;
            }
 
            // 更新粒子状态的方法
            update() {
                this.x += Math.cos(this.angle) * this.speed;
                this.y += Math.sin(this.angle) * this.speed;
                this.speed *= 0.99;
                this.life -= 1;
            }
 
            // 绘制粒子的方法
            draw() {
                ctx.fillStyle = this.color + ', ' + (this.life / 100) + ')';
                ctx.beginPath();
                ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
                ctx.fill();
            }
        }
 
        // 动画函数
        function animate() {
            // 绘制背景
            ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
 
            // 以5%的概率添加新烟花
            if (Math.random() < 0.05) {
                const x = random(0, canvas.width);
                const y = canvas.height;
                const fireworkColor = 'hsla(' + random(0, 360) + ', 100%, 50%';
                fireworks.push(new Firework(x, y, fireworkColor));
            }
 
            // 更新和绘制烟花
            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);
                }
            }

            // 显示文字
            ctx.font = "50px Arial";
            ctx.fillStyle = "pink";
            ctx.textAlign = "center";
            ctx.fillText("2024年龙年快乐", canvas.width / 2, canvas.height / 2);
 
            // 继续下一帧动画
            requestAnimationFrame(animate);
        }
 
        // 启动动画
        animate();
 
        // 监听窗口大小变化,重新设置画布大小
        window.addEventListener('resize', function() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });
 
        // 播放音乐的按钮点击事件
        const playButton = document.getElementById('playButton');
        const bgm = new Audio('background_music.mp3');
        playButton.addEventListener('click', function() {
            if (bgm.paused) {
                bgm.play();
                playButton.textContent = '暂停音乐';
            } else {
                bgm.pause();
                playButton.textContent = '播放音乐';
            }
        });
 
    </script>
</body>
</html>

OK!

Guess you like

Origin blog.csdn.net/cnds123/article/details/135320489