HTML5 Canvas龙卷风特效

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML5 Canvas龙卷风特效</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            height: 100vh;
            overflow: hidden;
            background: linear-gradient(to bottom, #1a1a2e 0%, #16213e 100%);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: Arial, sans-serif;
        }

        canvas {
            display: block;
            position: absolute;
            top: 0;
            left: 0;
        }

        .controls {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 10px;
            z-index: 2;
        }

        .control-btn {
            padding: 8px 15px;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .control-btn:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .intensity-display {
            color: white;
            padding: 8px 15px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 20px;
        }

        .title {
            position: absolute;
            top: 20px;
            left: 0;
            width: 100%;
            text-align: center;
            color: white;
            font-size: 2rem;
            text-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
            z-index: 2;
        }

        /* 版权信息 */
        .footer {
            position: absolute;
            bottom: 10px;
            right: 10px;
            color: rgba(255, 255, 255, 0.5);
            font-size: 12px;
            z-index: 3;
        }

        .footer a {
            color: #00f5d4;
            text-decoration: none;
        }

        .footer a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <h1 class="title">HTML5 Canvas龙卷风特效</h1>
    
    <canvas id="tornadoCanvas"></canvas>
    
    <div class="controls">
        <button class="control-btn" id="increaseBtn">增强</button>
        <div class="intensity-display">强度: <span id="intensityValue">5</span></div>
        <button class="control-btn" id="decreaseBtn">减弱</button>
    </div>
    
    <!-- 版权信息 -->
    <div class="footer">
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const canvas = document.getElementById('tornadoCanvas');
            const ctx = canvas.getContext('2d');
            const increaseBtn = document.getElementById('increaseBtn');
            const decreaseBtn = document.getElementById('decreaseBtn');
            const intensityValue = document.getElementById('intensityValue');
            
            // 设置画布大小为窗口大小
            function resizeCanvas() {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
            }
            
            window.addEventListener('resize', resizeCanvas);
            resizeCanvas();
            
            // 龙卷风参数
            let intensity = 5;
            let particles = [];
            const maxParticles = 500;
            
            // 粒子类
            class Particle {
                constructor() {
                    this.reset();
                    this.y = Math.random() * canvas.height;
                }
                
                reset() {
                    this.x = canvas.width / 2 + (Math.random() - 0.5) * 50;
                    this.y = -20;
                    this.size = Math.random() * 3 + 1;
                    this.speed = Math.random() * 3 + 1 * (intensity / 5);
                    this.angle = 0;
                    this.spin = Math.random() * 0.2 - 0.1;
                    this.radius = Math.random() * 10 + 5;
                    this.color = `rgba(200, 200, 200, ${Math.random() * 0.5 + 0.1})`;
                }
                
                update() {
                    this.angle += this.spin;
                    this.x = canvas.width / 2 + Math.cos(this.angle) * this.radius * (this.y / canvas.height * 2);
                    this.y += this.speed;
                    
                    // 增加随强度变化的水平移动
                    this.x += (Math.random() - 0.5) * intensity;
                    
                    // 粒子大小随高度变化
                    this.size = (1 - this.y / canvas.height) * 3 + 1;
                    
                    if (this.y > canvas.height) {
                        this.reset();
                    }
                }
                
                draw() {
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                    ctx.fillStyle = this.color;
                    ctx.fill();
                }
            }
            
            // 初始化粒子
            function initParticles() {
                particles = [];
                for (let i = 0; i < maxParticles * (intensity / 10); i++) {
                    particles.push(new Particle());
                }
            }
            
            initParticles();
            
            // 绘制龙卷风底部
            function drawTornadoBase() {
                const gradient = ctx.createRadialGradient(
                    canvas.width / 2, canvas.height, 0,
                    canvas.width / 2, canvas.height, canvas.width / 3
                );
                gradient.addColorStop(0, 'rgba(100, 100, 100, 0.8)');
                gradient.addColorStop(1, 'rgba(100, 100, 100, 0)');
                
                ctx.beginPath();
                ctx.ellipse(
                    canvas.width / 2, canvas.height, 
                    canvas.width / 3, 50, 
                    0, 0, Math.PI * 2
                );
                ctx.fillStyle = gradient;
                ctx.fill();
            }
            
            // 动画循环
            function animate() {
                ctx.fillStyle = 'rgba(26, 26, 46, 0.2)';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                
                drawTornadoBase();
                
                // 更新和绘制所有粒子
                particles.forEach(particle => {
                    particle.update();
                    particle.draw();
                });
                
                requestAnimationFrame(animate);
            }
            
            animate();
            
            // 控制按钮事件
            increaseBtn.addEventListener('click', function() {
                if (intensity < 10) {
                    intensity++;
                    intensityValue.textContent = intensity;
                    initParticles();
                }
            });
            
            decreaseBtn.addEventListener('click', function() {
                if (intensity > 1) {
                    intensity--;
                    intensityValue.textContent = intensity;
                    initParticles();
                }
            });
            
            // 鼠标移动影响龙卷风
            canvas.addEventListener('mousemove', function(e) {
                const mouseX = e.clientX;
                const dx = mouseX - canvas.width / 2;
                
                // 根据鼠标位置轻微影响粒子
                particles.forEach(particle => {
                    particle.x += dx * 0.0005 * particle.y;
                });
            });
        });
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值