网站已运行
22天 0时 50分 16秒

粒子爆炸效果:从零实现动态交互

小不© 允许规范转载
名人名言:谁对时间越吝

1. 功能概述

粒子爆炸效果的核心是通过点击按钮触发一系列粒子的动态散开,粒子在生命周期内逐渐消失,形成类似烟花的视觉效果。以下是实现的主要功能:

  • 粒子生成:在按钮点击时,从按钮中心生成多个粒子。

  • 粒子运动:粒子以随机方向和速度散开,同时带有旋转和减速效果。

  • 粒子生命周期:粒子在一定时间内逐渐消失,模拟自然衰减。

  • 动画循环:使用 requestAnimationFrame 实现流畅的动画效果。

2. 完整代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小不码学</title>
    <style>
        * {
            margin0;
            padding0;
            box-sizing: border-box;
        }

        body {
            height100vh;
            width100vw;
            background-color#1a1a1a;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .action-button {
            padding15px 30px;
            font-size18px;
            font-family: Arial, sans-serif;
            color: white;
            background-color#4a90e2;
            border: none;
            border-radius5px;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow0 4px 8px rgba(0000.2);
        }

        .action-button:hover {
            background-color#3a7bc8;
        }

        .action-button:active {
            transformscale(1.1);
            box-shadow0 2px 4px rgba(0000.2);
        }

        .particle-container {
            position: fixed;
            top0;
            left0;
            width100%;
            height100%;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <button>点击爆炸</button>
    <canvas id="particleCanvas"></canvas>

    <script>
        / 粒子效果核心逻辑
        const canvas = document.getElementById("particleCanvas");
        const ctx = canvas.getContext("2d");
        const button = document.querySelector(".action-button");

        / 调整画布大小
        function adjustCanvasSize() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }

        window.addEventListener("resize", adjustCanvasSize);
        adjustCanvasSize();

        / 粒子类
        class MagicParticle {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.angle = Math.random() * Math.PI * 2;
                this.speed = Math.random() * 4 + 2;
                this.vx = Math.cos(this.angle) * this.speed;
                this.vy = Math.sin(this.angle) * this.speed;
                this.size = Math.random() * 4 + 2;
                this.rotation = Math.random() * Math.PI * 2;
                this.rotationSpeed = (Math.random() - 0.5) * 0.1;
                this.lifespan = 2000;
                this.age = 0;
            }

            update(deltaTime) {
                this.x += this.vx;
                this.y += this.vy;
                this.vx *= 0.97;
                this.vy *= 0.97;
                this.rotation += this.rotationSpeed;
                this.age += deltaTime;
            }

            draw() {
                const opacity = Math.max(1 - this.age / this.lifespan0);
                ctx.save();
                ctx.translate(this.xthis.y);
                ctx.rotate(this.rotation);
                ctx.globalAlpha = opacity;

                / 绘制粒子
                ctx.beginPath();
                const spikes = 5;
                const outerRadius = this.size;
                const innerRadius = outerRadius * 0.5;

                for (let i = 0; i < spikes * 2; i++) {
                    const radius = i % 2 === 0 ? outerRadius : innerRadius;
                    const angle = (i * Math.PI) / spikes;
                    const x = Math.cos(angle) * radius;
                    const y = Math.sin(angle) * radius;

                    if (i === 0) {
                        ctx.moveTo(x, y);
                    } else {
                        ctx.lineTo(x, y);
                    }
                }

                ctx.closePath();
                ctx.fillStyle = `rgba(255, 180, 50, ${opacity})`;
                ctx.fill();
                ctx.restore();
            }
        }

        / 粒子集合
        let activeParticles = [];
        let lastTimestamp = 0;

        / 动画循环
        function renderParticles(timestamp) {
            const deltaTime = timestamp - lastTimestamp;
            lastTimestamp = timestamp;

            ctx.clearRect(00, canvas.width, canvas.height);

            activeParticles.forEach(particle => {
                particle.update(deltaTime);
                particle.draw();
            });

            activeParticles = activeParticles.filter(particle => particle.age < particle.lifespan);

            if (activeParticles.length > 0) {
                requestAnimationFrame(renderParticles);
            }
        }

        / 创建粒子爆炸
        function triggerExplosion(x, y) {
            const particleCount = Math.floor(Math.random() * 40) + 60;
            for (let i = 0; i < particleCount; i++) {
                activeParticles.push(new MagicParticle(x, y));
            }
            lastTimestamp = performance.now();
            requestAnimationFrame(renderParticles);
        }

        / 按钮点击事件
        button.addEventListener("click"(event) => {
            const buttonRect = button.getBoundingClientRect();
            const centerX = buttonRect.left + buttonRect.width / 2;
            const centerY = buttonRect.top + buttonRect.height / 2;

            triggerExplosion(centerX, centerY);
        });
    </script>
</body>
</html>复制


3. 核心实现解析

粒子类(MagicParticle

  • 构造函数:初始化粒子的位置、速度、大小和旋转角度。

  • update 方法:更新粒子的位置和状态,包括速度衰减和旋转。

  • draw 方法:绘制粒子,使用星形图案增强视觉效果。

动画循环

  • 使用 requestAnimationFrame 实现流畅的动画。

  • 通过 deltaTime 动态调整粒子的更新速度,确保动画在不同帧率下保持一致。

粒子生命周期

  • 每个粒子都有一个生命周期(lifespan),随着时间推移逐渐消失。

  • 透明度(opacity)随生命周期变化,模拟粒子的自然衰减。

4. 性能优化

  1. requestAnimationFrame 替代定时器

    • 使用 requestAnimationFrame 确保动画与屏幕刷新率同步,避免资源浪费。

  2. 粒子数量动态调整

    • 根据设备性能动态调整粒子数量,避免过度消耗资源。

  3. 透明度优化

    • 粒子的透明度随生命周期变化,减少不必要的绘制。

5. 应用场景

粒子爆炸效果适用于多种场景:

  • 按钮点击反馈:增强用户交互体验。

  • 游戏特效:用于爆炸、魔法等动态效果。

  • 视觉展示:用于广告、演示或艺术创作。

6. 总结

通过本文的实现,我们从零构建了一个粒子爆炸效果,并深入解析了其背后的实现原理。这种效果不仅具有视觉吸引力,还能通过优化实现流畅的动画和高效的资源利用。希望本文能为你的项目提供灵感,帮助你实现更丰富的动态交互效果!


相关标签

粒子爆炸效果
动态交互效果
HTML CSS 粒子爆炸效果
粒子动画