当前位置: 首页 > ds >正文

心形烟花优化展示效果

<!DOCTYPE html>
<html>
<head>
    <title>完整心形烟花特效</title>
    <style>
        body { 
            margin: 0;
            overflow: hidden;
            background: #000;
            font-family: Arial, sans-serif;
        }
        #controls {
            position: fixed;
            top: 20px;
            left: 20px;
            background: rgba(255,255,255,0.1);
            padding: 15px;
            border-radius: 8px;
        }
        button {
            padding: 8px 15px;
            background: #2196F3;
            border: none;
            color: white;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
    </style>
</head>
<body>
    <div id="controls">
        <button id="modeBtn">自动模式</button>
        <button id="clearBtn">清空</button>
    </div>
    <canvas id="canvas"></canvas>

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

// 画布自适应
function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();

// 心形生成算法
function generateHeartPoints(centerX, centerY) {
    const points = [];
    for(let t = 0; t < Math.PI*2; t += 0.015) {
        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 * 18,
            y: centerY + y * 18,
            hue: Math.random() * 360,
            size: Math.random() * 3 + 2
        });
    }
    return points;
}

// 烟花粒子类
class FireworkParticle {
    constructor(startX, startY, target) {
        this.x = startX;
        this.y = startY;
        this.target = target;
        this.speed = {
            x: (target.x - startX) * 0.04,
            y: (target.y - startY) * 0.04
        };
        this.alpha = 1;
    }

    update() {
        this.x += this.speed.x;
        this.y += this.speed.y;
        this.alpha -= 0.008;
    }

    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.particles = [];
        this.launchHeight = canvas.height;
        this.x = Math.random() * canvas.width;
        this.y = this.launchHeight;
        this.target = { x: targetX, y: targetY };
        this.speed = -15;
        this.exploded = false;
    }

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

    explode() {
        this.exploded = true;
        generateHeartPoints(this.target.x, this.target.y).forEach(point => {
            this.particles.push(new FireworkParticle(
                this.target.x,
                this.target.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%,70%,1)`;
            ctx.fill();
        } else {
            this.particles.forEach(p => p.draw());
        }
    }
}

// 控制系统
document.getElementById('modeBtn').addEventListener('click', () => {
    isAutoMode = !isAutoMode;
    modeBtn.textContent = isAutoMode ? '手动模式' : '自动模式';
});

document.getElementById('clearBtn').addEventListener('click', () => {
    fireworks = [];
});

canvas.addEventListener('click', e => {
    const rect = canvas.getBoundingClientRect();
    fireworks.push(new Firework(e.clientX - rect.left, e.clientY - rect.top));
});

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

    // 自动模式生成
    if(isAutoMode && fireworks.length < 5 && Math.random() < 0.03) {
        fireworks.push(new Firework(
            Math.random() * canvas.width,
            canvas.height * 0.3
        ));
    }

    // 更新所有烟花
    fireworks.forEach((fw, index) => {
        fw.update();
        fw.draw();
        if (fw.exploded && fw.particles.length === 0) {
            fireworks.splice(index, 1);
        }
    });

    requestAnimationFrame(animate);
}
animate();

// 移动端支持
canvas.addEventListener('touchstart', e => {
    e.preventDefault();
    const rect = canvas.getBoundingClientRect();
    const touch = e.touches[0];
    fireworks.push(new Firework(
        touch.clientX - rect.left,
        touch.clientY - rect.top
    ));
}, { passive: false });
</script>
</body>
</html>

http://www.xdnf.cn/news/2516.html

相关文章:

  • conda 常用命令
  • Docker:快速搭建 RabbitMQ 集群的技术指南
  • javaWeb开发---前后端开发全景图解(基础梳理 + 技术体系)
  • 【HarmonyOS 5】鸿蒙检测系统完整性
  • STM32F103_HAL库+寄存器学习笔记21 - CAN接收过滤器:CPU减负神器,提升系统效率的第一道防线
  • Ubuntu 磁盘空间占用清理(宝塔)
  • 创建一个springboot的项目-简洁步骤
  • 利用 Python 爬虫按关键字搜索 1688 商品详情:实战指南
  • 用户行为检测技术解析:从请求头到流量模式的对抗与防御
  • 大模型、知识图谱和强化学习三者的结合,可以形成哪些研究方向?
  • Java安全之cc链学习集合
  • 【C语言】fprintf与perror对比,两种报错提示的方法
  • 在Linux中,使用IO标准库进行读写操作。
  • Kubernetes学习笔记-环境变量的使用
  • 重构数字信任基石:Java 24 网络安全特性的全维度革新与未来防御体系构建
  • 30、不是说字符串是不可变的吗,string s=“abc“;s=“123“不就是变了吗?
  • HNUST湖南科技大学-嵌入式考试选择题题库(109道纠正详解版)
  • 电镀废水资源化利用的工艺介绍
  • 备份服务器,备份服务器数据有哪些方法可以实现?
  • Spark学习全总结
  • 多用户商城系统的三种形式:综合性、垂直型、社交型
  • MPI Code for Ghost Data Exchange in 3D Domain Decomposition with Multi-GPUs
  • ALTER TABLE 删除DROP表列的报错: 因为有一个或多个对象访问此列
  • 多通道示波器测量系统的工程实践与技术演进
  • Flink 时态维度表 Join 与缓存机制实战
  • (done) 吴恩达版提示词工程 8. 聊天机器人 (聊天格式设计,上下文内容,点餐机器人)
  • ppt流程图怎么?ppt流程图模板大全
  • 【C语言操作符详解(一)】--进制转换,原反补码,移位操作符,位操作符,逗号表达式,下标访问及函数调用操作符
  • 自动驾驶(ADAS)领域常用数据集介绍
  • 学习insightface 的人脸识别