告别枯燥!用JavaScript打造一个会跟你互动的动态彩色呼吸灯

动态彩色呼吸灯互动页面

我将为你创建一个有趣的互动式彩色呼吸灯页面,它会根据你的鼠标移动和点击产生动态响应效果。

设计思路

  • 创建一个中心呼吸灯,颜色会平滑过渡

  • 鼠标移动时产生跟随粒子效果

  • 点击页面会生成彩色涟漪

  • 添加声音反馈增强互动体验

  • 响应式设计适应不同屏幕

下面是完整的实现代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>互动彩色呼吸灯</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            background: #000;
            overflow: hidden;
            font-family: 'Arial', sans-serif;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
        }
        
        .container {
            position: relative;
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }
        
        .breathing-light {
            width: 200px;
            height: 200px;
            border-radius: 50%;
            position: relative;
            box-shadow: 
                0 0 20px #fff,
                0 0 40px #fff,
                0 0 60px #fff,
                0 0 80px #0ff,
                0 0 100px #0ff,
                0 0 140px #0ff,
                0 0 200px #0ff;
            animation: breathe 4s infinite alternate, colorChange 10s infinite;
            z-index: 10;
        }
        
        .instructions {
            position: absolute;
            bottom: 20px;
            text-align: center;
            background: rgba(0, 0, 0, 0.5);
            padding: 10px 20px;
            border-radius: 10px;
            z-index: 20;
        }
        
        .particle {
            position: absolute;
            border-radius: 50%;
            pointer-events: none;
            z-index: 5;
        }
        
        .ripple {
            position: absolute;
            border-radius: 50%;
            border: 2px solid rgba(255, 255, 255, 0.8);
            transform: translate(-50%, -50%);
            animation: rippleEffect 1.5s linear;
            z-index: 1;
        }
        
        @keyframes breathe {
            0% {
                transform: scale(0.8);
                box-shadow: 
                    0 0 20px #fff,
                    0 0 40px #fff,
                    0 0 60px #fff,
                    0 0 80px #0ff,
                    0 0 100px #0ff,
                    0 0 140px #0ff,
                    0 0 200px #0ff;
            }
            100% {
                transform: scale(1.2);
                box-shadow: 
                    0 0 30px #fff,
                    0 0 60px #fff,
                    0 0 90px #fff,
                    0 0 120px #0ff,
                    0 0 150px #0ff,
                    0 0 200px #0ff,
                    0 0 250px #0ff;
            }
        }
        
        @keyframes colorChange {
            0% { background-color: #ff0080; }
            20% { background-color: #8000ff; }
            40% { background-color: #0080ff; }
            60% { background-color: #00ff80; }
            80% { background-color: #ffff00; }
            100% { background-color: #ff0080; }
        }
        
        @keyframes rippleEffect {
            0% {
                width: 0;
                height: 0;
                opacity: 1;
            }
            100% {
                width: 500px;
                height: 500px;
                opacity: 0;
            }
        }
        
        .controls {
            position: absolute;
            top: 20px;
            display: flex;
            gap: 10px;
            z-index: 20;
        }
        
        button {
            background: rgba(255, 255, 255, 0.2);
            border: 1px solid rgba(255, 255, 255, 0.5);
            color: white;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        button:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: scale(1.05);
        }
        
        .title {
            position: absolute;
            top: 20px;
            font-size: 2.5rem;
            text-shadow: 0 0 10px #0ff, 0 0 20px #0ff;
            animation: glow 2s infinite alternate;
        }
        
        @keyframes glow {
            from { text-shadow: 0 0 10px #0ff, 0 0 20px #0ff; }
            to { text-shadow: 0 0 20px #0ff, 0 0 30px #0ff, 0 0 40px #0ff; }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="title">互动呼吸灯</h1>
        
        <div class="controls">
            <button id="soundToggle">声音: 开</button>
            <button id="reset">重置效果</button>
        </div>
        
        <div class="breathing-light"></div>
        
        <div class="instructions">
            <p>移动鼠标产生粒子效果 | 点击页面产生涟漪 | 享受这个互动体验!</p>
        </div>
    </div>

    <script>
        // 音频上下文(用于声音效果)
        let audioContext;
        let soundEnabled = true;
        
        // 初始化音频
        function initAudio() {
            try {
                audioContext = new (window.AudioContext || window.webkitAudioContext)();
            } catch (e) {
                console.log("Web Audio API is not supported in this browser");
                soundEnabled = false;
                document.getElementById('soundToggle').textContent = "声音: 不支持";
                document.getElementById('soundToggle').disabled = true;
            }
        }
        
        // 创建声音效果
        function playSound(frequency, duration, type = 'sine') {
            if (!soundEnabled || !audioContext) return;
            
            const oscillator = audioContext.createOscillator();
            const gainNode = audioContext.createGain();
            
            oscillator.connect(gainNode);
            gainNode.connect(audioContext.destination);
            
            oscillator.type = type;
            oscillator.frequency.value = frequency;
            
            gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration);
            
            oscillator.start(audioContext.currentTime);
            oscillator.stop(audioContext.currentTime + duration);
        }
        
        // 创建粒子效果
        function createParticle(x, y) {
            const particle = document.createElement('div');
            particle.classList.add('particle');
            
            // 随机大小和颜色
            const size = Math.random() * 10 + 5;
            const colors = ['#ff0080', '#8000ff', '#0080ff', '#00ff80', '#ffff00', '#ff8000'];
            const color = colors[Math.floor(Math.random() * colors.length)];
            
            particle.style.width = `${size}px`;
            particle.style.height = `${size}px`;
            particle.style.background = color;
            particle.style.left = `${x}px`;
            particle.style.top = `${y}px`;
            particle.style.boxShadow = `0 0 ${size}px ${color}`;
            
            document.body.appendChild(particle);
            
            // 随机移动方向
            const moveX = (Math.random() - 0.5) * 4;
            const moveY = (Math.random() - 0.5) * 4;
            
            // 动画
            let opacity = 1;
            const fadeInterval = setInterval(() => {
                opacity -= 0.02;
                particle.style.opacity = opacity;
                
                const currentX = parseFloat(particle.style.left);
                const currentY = parseFloat(particle.style.top);
                
                particle.style.left = `${currentX + moveX}px`;
                particle.style.top = `${currentY + moveY}px`;
                
                if (opacity <= 0) {
                    clearInterval(fadeInterval);
                    particle.remove();
                }
            }, 30);
        }
        
        // 创建涟漪效果
        function createRipple(x, y) {
            const ripple = document.createElement('div');
            ripple.classList.add('ripple');
            
            // 随机颜色
            const colors = ['#ff0080', '#8000ff', '#0080ff', '#00ff80', '#ffff00', '#ff8000'];
            const color = colors[Math.floor(Math.random() * colors.length)];
            
            ripple.style.borderColor = color;
            ripple.style.left = `${x}px`;
            ripple.style.top = `${y}px`;
            
            document.body.appendChild(ripple);
            
            // 播放声音
            if (soundEnabled) {
                playSound(300 + Math.random() * 500, 0.5, 'sine');
            }
            
            // 移除元素
            setTimeout(() => {
                ripple.remove();
            }, 1500);
        }
        
        // 鼠标移动事件
        let mouseX = 0;
        let mouseY = 0;
        let particleTimer = null;
        
        document.addEventListener('mousemove', (e) => {
            mouseX = e.clientX;
            mouseY = e.clientY;
            
            // 限制粒子生成频率
            if (!particleTimer) {
                createParticle(mouseX, mouseY);
                particleTimer = setTimeout(() => {
                    particleTimer = null;
                }, 50);
            }
        });
        
        // 点击事件
        document.addEventListener('click', (e) => {
            createRipple(e.clientX, e.clientY);
            
            // 在点击位置创建更多粒子
            for (let i = 0; i < 10; i++) {
                setTimeout(() => {
                    createParticle(e.clientX + (Math.random() - 0.5) * 100, 
                                  e.clientY + (Math.random() - 0.5) * 100);
                }, i * 50);
            }
        });
        
        // 触摸事件支持(移动设备)
        document.addEventListener('touchmove', (e) => {
            e.preventDefault();
            const touch = e.touches[0];
            mouseX = touch.clientX;
            mouseY = touch.clientY;
            
            if (!particleTimer) {
                createParticle(mouseX, mouseY);
                particleTimer = setTimeout(() => {
                    particleTimer = null;
                }, 100);
            }
        });
        
        document.addEventListener('touchstart', (e) => {
            e.preventDefault();
            const touch = e.touches[0];
            createRipple(touch.clientX, touch.clientY);
        });
        
        // 按钮事件
        document.getElementById('soundToggle').addEventListener('click', function() {
            soundEnabled = !soundEnabled;
            this.textContent = `声音: ${soundEnabled ? '开' : '关'}`;
            
            // 播放测试声音
            if (soundEnabled) {
                playSound(440, 0.2, 'sine');
            }
        });
        
        document.getElementById('reset').addEventListener('click', function() {
            // 移除所有粒子和涟漪
            document.querySelectorAll('.particle, .ripple').forEach(el => el.remove());
            
            // 播放重置声音
            if (soundEnabled) {
                playSound(220, 0.3, 'square');
            }
        });
        
        // 页面加载完成后初始化
        window.addEventListener('load', function() {
            initAudio();
            
            // 显示欢迎效果
            setTimeout(() => {
                createRipple(window.innerWidth / 2, window.innerHeight / 2);
                
                if (soundEnabled) {
                    playSound(523.25, 0.5, 'sine');
                    setTimeout(() => playSound(659.25, 0.5, 'sine'), 200);
                    setTimeout(() => playSound(783.99, 0.8, 'sine'), 400);
                }
            }, 500);
        });
        
        // 窗口大小变化时调整
        window.addEventListener('resize', function() {
            // 确保呼吸灯居中
            document.querySelector('.breathing-light').style.margin = 'auto';
        });
    </script>
</body>
</html>

功能说明

  1. 呼吸灯效果:中心灯会平滑地改变大小和颜色,模拟呼吸效果

  2. 鼠标互动

    • 移动鼠标会产生彩色粒子跟随效果

    • 点击页面会在点击位置产生彩色涟漪

  3. 声音反馈

    • 点击和互动时有声音效果

    • 可以开关声音

  4. 控制功能

    • 声音开关按钮

    • 重置效果按钮

  5. 响应式设计:适应不同屏幕尺寸

  6. 触摸支持:在移动设备上也可以正常使用

使用提示

  • 移动鼠标体验粒子跟随效果

  • 点击页面任意位置创建彩色涟漪

  • 尝试开关声音体验不同的互动感受

  • 点击"重置效果"清除所有粒子

这个页面结合了视觉和听觉效果,创造了一个沉浸式的互动体验。你可以直接复制上面的代码到HTML文件中,用浏览器打开即可体验!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值