酷秀  - kxiu.cn

用Ai写的音乐节奏可视化背景

admin的头像admin4个月前教程97热度

Screenshot_20250916_151937.jpg

思路分析

  1. 使用Web Audio API分析正在播放的音频
  2. 通过AnalyserNode获取频率数据
  3. 根据音乐节奏和强度动态调整背景效果
  4. 创建视觉上吸引人的跳动效果

实现方案

下面是完整的HTML代码,包含了所有必要的CSS和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 {
            font-family: 'Arial', sans-serif;
            min-height: 100vh;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            background: linear-gradient(135deg, #6e8efb, #a777e3);
            transition: background 0.2s ease;
        }

        .container {
            text-align: center;
            padding: 2rem;
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
            z-index: 10;
            max-width: 90%;
            width: 500px;
        }

        h1 {
            color: white;
            margin-bottom: 1.5rem;
            text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
        }

        .controls {
            display: flex;
            flex-direction: column;
            gap: 1rem;
            margin-bottom: 1.5rem;
        }

        input[type="file"] {
            display: none;
        }

        label, button {
            padding: 12px 20px;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-weight: bold;
        }

        label:hover, button:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: translateY(-2px);
        }

        .visualization {
            height: 150px;
            width: 100%;
            margin-top: 1.5rem;
            display: flex;
            justify-content: center;
            align-items: flex-end;
            gap: 2px;
        }

        .bar {
            width: 8px;
            background: white;
            border-radius: 4px 4px 0 0;
            opacity: 0.8;
        }

        .audio-info {
            color: white;
            margin-top: 1rem;
            font-size: 0.9rem;
            opacity: 0.8;
        }

        .pulse {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
            opacity: 0.5;
            border-radius: 50%;
            transform: scale(1);
            background: radial-gradient(circle, #ff00cc 0%, rgba(0,0,0,0) 70%);
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>音乐节奏可视化器</h1>
        <div class="controls">
            <input type="file" id="audioFile" accept="audio/*" />
            <label for="audioFile">选择音频文件</label>
            <button id="playBtn" disabled>播放</button>
            <button id="stopBtn" disabled>停止</button>
        </div>
        <div class="visualization" id="visualization"></div>
        <p class="audio-info" id="audioInfo">请选择音频文件开始播放</p>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const audioFileInput = document.getElementById('audioFile');
            const playBtn = document.getElementById('playBtn');
            const stopBtn = document.getElementById('stopBtn');
            const audioInfo = document.getElementById('audioInfo');
            const visualization = document.getElementById('visualization');

            let audioContext;
            let audioElement;
            let analyser;
            let source;
            let dataArray;
            let bars = [];
            let isPlaying = false;
            let animationId;
            let pulseElements = [];

            // 创建可视化条
            for (let i = 0; i < 64; i++) {
                const bar = document.createElement('div');
                bar.className = 'bar';
                visualization.appendChild(bar);
                bars.push(bar);
            }

            // 选择音频文件
            audioFileInput.addEventListener('change', function(e) {
                const file = e.target.files[0];
                if (!file) return;

                if (audioElement) {
                    audioElement.pause();
                    if (animationId) cancelAnimationFrame(animationId);
                }

                const url = URL.createObjectURL(file);
                audioElement = new Audio(url);

                audioInfo.textContent = `已选择: ${file.name}`;
                playBtn.disabled = false;
                stopBtn.disabled = false;

                setupAudioContext();
            });

            // 播放按钮
            playBtn.addEventListener('click', function() {
                if (!audioElement || isPlaying) return;

                audioElement.play();
                isPlaying = true;
                playBtn.textContent = '暂停';
                animate();
            });

            // 停止按钮
            stopBtn.addEventListener('click', function() {
                if (!audioElement) return;

                audioElement.pause();
                audioElement.currentTime = 0;
                isPlaying = false;
                playBtn.textContent = '播放';

                // 重置可视化
                bars.forEach(bar => {
                    bar.style.height = '0px';
                });

                // 移除所有脉冲效果
                pulseElements.forEach(el => el.remove());
                pulseElements = [];
            });

            // 设置音频上下文
            function setupAudioContext() {
                if (audioContext) return;

                audioContext = new (window.AudioContext || window.webkitAudioContext)();
                analyser = audioContext.createAnalyser();
                analyser.fftSize = 256;

                source = audioContext.createMediaElementSource(audioElement);
                source.connect(analyser);
                analyser.connect(audioContext.destination);

                dataArray = new Uint8Array(analyser.frequencyBinCount);
            }

            // 动画循环
            function animate() {
                if (!isPlaying) return;

                analyser.getByteFrequencyData(dataArray);

                // 更新条形图
                for (let i = 0; i < bars.length; i++) {
                    const value = dataArray[i];
                    const height = value * 1.5;
                    bars[i].style.height = height + 'px';
                }

                // 计算平均音量
                let sum = 0;
                for (let i = 0; i < dataArray.length; i++) {
                    sum += dataArray[i];
                }
                const average = sum / dataArray.length;

                // 根据音量改变背景
                changeBackground(average);

                // 根据节奏创建脉冲效果
                if (average > 80) {
                    createPulseEffect(average);
                }

                animationId = requestAnimationFrame(animate);
            }

            // 改变背景
            function changeBackground(volume) {
                const intensity = volume / 256;

                // 改变背景色
                const hue = (intensity * 60 + 240) % 360;
                document.body.style.background = `linear-gradient(135deg, hsl(${hue}, 80%, 60%), hsl(${(hue + 60) % 360}, 80%, 60%))`;

                // 添加跳动效果
                document.body.style.transform = `scale(${1 + intensity * 0.05})`;
                setTimeout(() => {
                    document.body.style.transform = 'scale(1)';
                }, 100);
            }

            // 创建脉冲效果
            function createPulseEffect(volume) {
                const pulse = document.createElement('div');
                pulse.className = 'pulse';

                const x = Math.random() * window.innerWidth;
                const y = Math.random() * window.innerHeight;
                const size = 50 + (volume / 256) * 200;
                const hue = Math.random() * 360;

                pulse.style.left = `${x}px`;
                pulse.style.top = `${y}px`;
                pulse.style.width = `${size}px`;
                pulse.style.height = `${size}px`;
                pulse.style.background = `radial-gradient(circle, hsl(${hue}, 100%, 70%) 0%, rgba(0,0,0,0) 70%)`;

                document.body.appendChild(pulse);
                pulseElements.push(pulse);

                // 动画
                let scale = 1;
                const grow = setInterval(() => {
                    scale += 0.05;
                    pulse.style.transform = `scale(${scale})`;
                    pulse.style.opacity = 1 - (scale - 1) / 2;

                    if (scale > 3) {
                        clearInterval(grow);
                        pulse.remove();
                        const index = pulseElements.indexOf(pulse);
                        if (index > -1) {
                            pulseElements.splice(index, 1);
                        }
                    }
                }, 50);
            }
        });
    </script>
</body>
</html>
签名: 最忠诚的BUG开发者来自: 重庆市. Chrome浏览器
文章目录

新年快乐

×
新年快乐
同喜