放爱心烟花

<!DOCTYPE html>
<html>
<head>
    <title>心形烟花特效</title>
    <style>
        body { margin: 0; overflow: hidden; background: #000; }
        #modeBtn {
            position: fixed; top: 20px; left: 20px;
            padding: 10px; background: rgba(255,255,255,0.2);
            color: white; border: none; cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="modeBtn">自动模式</button>
    <canvas id="canvas"></canvas>

<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let isAutoMode = false;
const modeBtn = document.getElementById('modeBtn');

// 心形生成算法优化(增强粒子密度与尺寸)
function generateHeartPoints(centerX, centerY) {
    const points = [];
    for(let t=0; t < Math.PI*2; t += 0.03) { // 增加采样密度
        const x = 16 * Math.pow(Math.sin(t),3);
        const y = -13*Math.cos(t) + 5*Math.cos(2*t) + 2*Math.cos(3*t) + Math.cos(4*t);
        points.push({
            x: centerX + x*12,  // 放大系数提升至12
            y: centerY + y*12,
            size: Math.random()*4 + 2, // 粒子尺寸增大
            hue: Math.random()*360
        });
    }
    return points;
}

// 粒子类(增加运动阻尼与颜色动态)
class Particle {
    constructor(x, y, target) {
        this.x = x;
        this.y = y;
        this.target = target;
        this.speed = { x: 0, y: 0 };
        this.alpha = 1;
        this.friction = 0.93; // 增加运动阻尼
    }

    update() {
        // 向心形目标点加速
        const dx = this.target.x - this.x;
        const dy = this.target.y - this.y;
        this.speed.x += dx * 0.02;
        this.speed.y += dy * 0.02;
        
        // 物理模拟
        this.x += this.speed.x;
        this.y += this.speed.y;
        this.speed.x *= this.friction;
        this.speed.y *= this.friction;
        this.alpha -= 0.006; // 延长显示时间
    }

    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.target.size, 0, Math.PI*2);
        ctx.fillStyle = `hsla(${this.target.hue},100%,60%,${this.alpha})`;
        ctx.fill();
    }
}

// 烟花发射器(增加上升轨迹)
class Firework {
    constructor(targetX, targetY) {
        this.x = Math.random()*canvas.width;
        this.y = canvas.height;
        this.targetY = targetY || canvas.height/3;
        this.particles = [];
        this.speed = -12; // 提升上升速度
        this.exploded = false;
    }

    update() {
        if (!this.exploded) {
            this.y += this.speed;
            if (this.y <= this.targetY) this.explode();
        } else {
            this.particles.forEach(p => p.update());
            this.particles = this.particles.filter(p => p.alpha > 0);
        }
    }

    explode() {
        this.exploded = true;
        const heartPoints = generateHeartPoints(this.x, this.y);
        heartPoints.forEach(point => {
            this.particles.push(new Particle(this.x, this.y, point));
        });
    }

    draw() {
        if (!this.exploded) {
            // 绘制上升轨迹
            ctx.beginPath();
            ctx.arc(this.x, this.y, 3, 0, Math.PI*2);
            ctx.fillStyle = `hsla(${Math.random()*360},100%,60%,1)`;
            ctx.fill();
        } else {
            this.particles.forEach(p => p.draw());
        }
    }
}

// 控制系统(优化自动模式)
let fireworks = [];
modeBtn.addEventListener('click', () => {
    isAutoMode = !isAutoMode;
    modeBtn.textContent = isAutoMode ? '手动模式' : '自动模式';
});

canvas.addEventListener('click', e => {
    fireworks.push(new Firework(e.clientX, e.clientY));
});

// 动画循环(性能优化)
function animate() {
    ctx.fillStyle = 'rgba(0,0,0,0.08)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 自动模式生成(限制最大数量)
    if(isAutoMode && fireworks.length < 4 && Math.random() < 0.04) {
        fireworks.push(new Firework());
    }

    fireworks.forEach((fw, index) => {
        fw.update();
        fw.draw();
        if (fw.exploded && fw.particles.length === 0) {
            fireworks.splice(index, 1);
        }
    });
    requestAnimationFrame(animate);
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
animate();

// 画布尺寸自适应
function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
</script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tqs_12345

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值