JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>转轮 + 爆炸贴 + 白色烟花效果示例</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="price-card">
        <!-- 动态光效 -->
        <div class="light-effect"></div>

        <!-- 转轮SVG -->
        <svg class="explosion-svg" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="40" stroke="orange" stroke-width="5" fill="none" />
            <line x1="50" y1="10" x2="50" y2="30" stroke="orange" stroke-width="5" />
            <line x1="50" y1="70" x2="50" y2="90" stroke="orange" stroke-width="5" />
            <line x1="10" y1="50" x2="30" y2="50" stroke="orange" stroke-width="5" />
            <line x1="70" y1="50" x2="90" y2="50" stroke="orange" stroke-width="5" />
            <!-- 新增辐条 -->
        </svg>
        <svg class="explosion-svg1" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="40" stroke="orange" stroke-width="5" fill="none" />
            <line x1="50" y1="10" x2="50" y2="30" stroke="orange" stroke-width="5" />
            <line x1="50" y1="70" x2="50" y2="90" stroke="orange" stroke-width="5" />
            <line x1="10" y1="50" x2="30" y2="50" stroke="orange" stroke-width="5" />
            <line x1="70" y1="50" x2="90" y2="50" stroke="orange" stroke-width="5" />
            <!-- 新增辐条 -->
        </svg>
        <!-- 爆炸效果 -->
        <div class="explosion explosion1"></div>
        <div class="explosion explosion2"></div>
        <div class="explosion explosion3"></div>
    
        <!-- 价格标签 -->
        <span class="sale-price">活动特价:62.9元</span>
        <span class="regular-price">80元</span>
        
        <!-- 烟花画布 -->
        <canvas id="fireworkCanvas"></canvas>
    </div>

</body>
</html>

CSS

/* 爆炸贴卡片容器 */
.price-card {
    position: relative;
    display: inline-block;
    padding: 40px 60px;
    background-color: #ff4757; /* 爆炸贴背景色 */
    border-radius: 25px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
    overflow: hidden;
    cursor: pointer;
    transition: transform 0.3s ease;
    /* 添加转轮效果 */
    animation: rotate 10s linear infinite;
}


/* 转轮SVG样式 */
.explosion-svg {
    position: absolute;
    top: 8px;
    left: 5%;
    width: 120px;
    height: 120px;
    animation: spinWheel 2s linear infinite;
    z-index: 2;
    filter: drop-shadow(0 0 10px rgba(255, 165, 0, 0.7));
}
/* 转轮SVG样式 */
.explosion-svg1 {
    position: absolute;
    top: 8px;
    left: 65%;
    width: 120px;
    height: 120px;
    animation: spinWheel 2s linear infinite;
    z-index: 2;
    filter: drop-shadow(0 0 10px rgba(255, 165, 0, 0.7));
}
/* 转轮旋转动画 */
@keyframes spinWheel {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* 爆炸效果 */
.explosion {
    position: absolute;
    width: 40px;
    height: 40px;
    background: radial-gradient(circle, rgba(255,255,255,0.3) 0%, rgba(255,0,0,0) 70%); /* 调低透明度 */
    border-radius: 50%;
    opacity: 0;
    animation: explode 0.7s forwards;
    pointer-events: none;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.5);
    z-index: 1;
    filter: blur(2px); /* 添加模糊效果 */
}

/* 爆炸动画 */
@keyframes explode {
    0% {
        transform: translate(-50%, -50%) scale(0.5);
        opacity: 1;
    }
    50% {
        transform: translate(-50%, -50%) scale(2);
        opacity: 0.5;
    }
    100% {
        transform: translate(-50%, -50%) scale(3);
        opacity: 0;
    }
}

.explosion1 {
    background: radial-gradient(circle, rgba(255,255,255,0.3) 0%, rgba(255,0,0,0) 70%);
    animation: explode 0.7s forwards;
}

.explosion2 {
    background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, rgba(255,0,0,0) 70%);
    animation: explode 0.7s forwards 0.2s; /* 延迟启动 */
}

.explosion3...

JavaScript

// script.js

document.addEventListener('DOMContentLoaded', function() {
    const priceCard = document.querySelector('.price-card');
    const explosions = document.querySelectorAll('.explosion');
    const canvas = document.getElementById('fireworkCanvas');
    const ctx = canvas.getContext('2d');

    // 设置Canvas尺寸
    function resizeCanvas() {
        canvas.width = priceCard.offsetWidth;
        canvas.height = priceCard.offsetHeight;
    }
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);

    // 烟花粒子类
    class Particle {
        constructor(x, y, color) {
            this.x = x;
            this.y = y;
            this.size = Math.random() * 3 + 1;
            this.speedX = Math.random() * 4 - 2; // 增加水平速度范围
            this.speedY = Math.random() * 5 - 4; // 增加垂直速度,使粒子飞得更高
            this.color = color;
            this.gravity = 0.01; // 减少重力影响
            this.opacity = 1;
            this.fade = Math.random() * 0.02 + 0.01; // 调整粒子消散速度
            this.trail = []; // 记录粒子的轨迹
            this.maxTrail = 5; // 最大轨迹长度
        }

        update() {
            this.x += this.speedX;
            this.y += this.speedY;
            this.speedY += this.gravity;
            this.opacity -= this.fade;

            // 更新轨迹
            this.trail.push({x: this.x, y: this.y});
            if(this.trail.length > this.maxTrail){
                this.trail.shift();
            }
        }

        draw() {
            ctx.save();
            ctx.globalAlpha = this.opacity;
            ctx.fillStyle = this.color;
            // 绘制轨迹
            this.trail.forEach((point, index) => {
                ctx.beginPath();
                ctx.arc(point.x, point.y, this.size, 0, Math.PI * 2);
                ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
                ctx.fill();
            });
            // 绘制当前粒子
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fill();
          ...