玄之 发表于 2025-3-12 10:11:58

HTML&CSS&JS:必学!用粒子爆炸效果,让按钮点击 “告别枯燥”

这段代码通过 HTML、CSS 和 JavaScript 实现了一个动态的粒子爆炸效果,适合用于按钮点击反馈或特殊效果展示。

演示效果



HTML&CSS
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>公众号关注:前端Hardy</title>
    <style>
      html,
      body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            height: 100%;
            background: #222;
      }

      #explosion-button {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            padding: 15px 30px;
            font-size: 18px;
            font-family: sans-serif;
            color: #fff;
            background-color: #3498db;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: transform 0.2s ease-out;
      }

      #explosion-button.active {
            transform: translate(-50%, -50%) scale(1.2);
      }

      #particle-canvas {
            position: fixed;
            top: 0;
            left: 0;
            pointer-events: none;
      }
    </style>
</head>

<body>
    <button id="explosion-button">点赞收藏</button>
    <canvas id="particle-canvas"></canvas>
    <script>
      const button = document.getElementById("explosion-button");
      const canvas = document.getElementById("particle-canvas");
      const ctx = canvas.getContext("2d");

      function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
      }
      window.addEventListener("resize", resizeCanvas);
      resizeCanvas();

      class Particle {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                const angle = Math.random() * Math.PI * 2;
                const speed = Math.random() * 3 + 2;
                this.vx = Math.cos(angle) * speed;
                this.vy = Math.sin(angle) * speed;
                this.radius = Math.random() * 3 + 3;
                this.rotation = Math.random() * Math.PI * 2;
                this.rotationSpeed = (Math.random() - 0.5) * 0.2;

                this.life = 3000;
                this.elapsed = 0;
            }

            update(dt) {
                this.x += this.vx;
                this.y += this.vy;
                this.vx *= 0.98;
                this.vy *= 0.98;
                this.rotation += this.rotationSpeed;
                this.elapsed += dt;
            }

            draw(ctx) {
                const progress = this.elapsed / this.life;
                const alpha = Math.max(1 - progress, 0);
                ctx.save();
                ctx.translate(this.x, this.y);
                ctx.rotate(this.rotation);
                ctx.globalAlpha = alpha;
                const spikes = 4;
                const outerRadius = this.radius;
                const innerRadius = outerRadius * 0.5;

                ctx.beginPath();
                for (let i = 0; i < spikes * 2; i++) {
                  const r = (i % 2 === 0) ? outerRadius : innerRadius;
                  const angle = (i * Math.PI) / spikes;
                  const x = Math.cos(angle) * r;
                  const y = Math.sin(angle) * r;
                  if (i === 0) {
                        ctx.moveTo(x, y);
                  } else {
                        ctx.lineTo(x, y);
                  }
                }
                ctx.closePath();
                ctx.fillStyle = "rgba(255, 200, 0, 1)";
                ctx.fill();
                ctx.restore();
            }
      }

      let particles = [];

      let lastTime = 0;

      function animate(time) {
            const dt = time - lastTime;
            lastTime = time;

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

            particles.forEach((p) => {
                p.update(dt);
                p.draw(ctx);
            });

            particles = particles.filter((p) => p.elapsed < p.life);

            if (particles.length > 0) {
                requestAnimationFrame(animate);
            }
      }

      function createParticles(x, y) {
            const count = Math.floor(Math.random() * 30) + 50;
            for (let i = 0; i < count; i++) {
                particles.push(new Particle(x, y));
            }
            lastTime = performance.now();
            requestAnimationFrame(animate);
      }

      button.addEventListener("click", function (e) {
            const rect = button.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;

            button.classList.add("active");

            setTimeout(() => {
                button.classList.remove("active");
            }, 200);

            createParticles(centerX, centerY);
      });
    </script>
</body>

</html>

HTML 结构


[*]explosion-button:定义一个按钮,显示“点赞收藏”。
[*]particle-canvas:定义一个画布,用于绘制粒子效果。


CSS 样式


[*]html, body:设置页面背景颜色为#222,并移除滚动条。
[*]#explosion-button:定义按钮的样式,包括位置、大小、背景颜色、文字颜色和交互效果。
[*]使用 transform: translate(-50%, -50%)将按钮居中。
[*]添加:active 伪类实现按钮点击时的放大效果。
[*]#particle-canvas:定义画布的样式,使其覆盖整个页面,并设置 pointer-events: none 以避免干扰鼠标事件。


JavaScript 功能说明


[*]resizeCanvas:根据窗口大小调整画布的宽高。
[*]Particle 类:定义粒子的属性和行为。每个粒子具有位置、速度、半径、旋转角度和生命周期。update 方法更新粒子的位置和状态。draw 方法绘制粒子,使用 ctx.beginPath 和 ctx.fill 创建星形图案。
[*]animate 函数:动画循环,更新和绘制所有粒子。使用 requestAnimationFrame 实现流畅的动画效果。
[*]createParticles 函数:在指定位置生成多个粒子。
[*]按钮点击时,添加 active 类实现放大效果。在按钮中心位置生成粒子效果。
页: [1]
查看完整版本: HTML&CSS&JS:必学!用粒子爆炸效果,让按钮点击 “告别枯燥”