IF YOU

音乐播放器
00:00
00:00 / 00:00
    // 播放器全局配置 const CONFIG = { // 基础配置 defaultVolume: 1.0, // 默认音量设置为最大 autoPlay: false, // 默认不自动播放 // 歌词配置 lyricsDefaultCollapsed: false, // 歌词默认不折叠 lyricsToggleable: true, // 允许切换歌词折叠状态 lyricsMaxHeight: ‘350px’, // 歌词容器最大高度 lyricsFontSize: ’14px’, // 歌词字体大小 // 音频资源配置 audioSource: { online: ‘https://fanym.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2024/09/ifyou.mp3’ // 在线音频文件路径 }, // 歌词资源配置 lyricsSource: { online: ‘https://fanym.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2024/09/ifyou.lrc’ // 在线歌词文件路径 }, // UI配置 ui: { primaryColor: ‘#87CEEB’, // 主题色(天蓝色) activeColor: ‘#d9534f’, // 激活状态颜色(红色) translationColor: ‘#337ab7’, // 翻译文本颜色(蓝色) backgroundColor: ‘#f3f3f3’, // 背景色(浅灰色) wavesOpacity: 0.6 // 波浪动画透明度 } }; // 环境检测 const AUDIO_URL = CONFIG.audioSource.online; const LYRICS_URL = CONFIG.lyricsSource.online; // 工具函数集合 const Utils = { /** * 将秒数格式化为 MM:SS 格式的时间字符串 * @param {number} seconds – 需要格式化的秒数 * @returns {string} 格式化后的时间字符串,例如:”03:45″ */ formatTime: (seconds) => { const minutes = Math.floor(seconds / 60); seconds = Math.floor(seconds % 60); return `${minutes.toString().padStart(2, ‘0’)}:${seconds.toString().padStart(2, ‘0’)}`; }, /** * 解析LRC歌词中的时间戳为秒数 * @param {Array} timeMatch – 正则匹配到的时间戳数组 [完整匹配, 分钟, 秒, 毫秒] * @returns {number} 转换后的秒数 */ parseTimestamp: (timeMatch) => { const minutes = parseInt(timeMatch[1], 10); const seconds = parseInt(timeMatch[2], 10); const milliseconds = parseInt(timeMatch[3].padEnd(2, ‘0’), 10); return minutes * 60 + seconds + milliseconds / 100; }, /** * 防抖函数,用于限制函数的执行频率 * @param {Function} func – 需要防抖的函数 * @param {number} wait – 等待时间(毫秒) * @returns {Function} 防抖处理后的函数 */ debounce: (func, wait) => { let timeout; return function executedFunction(…args) { const later = () => { clearTimeout(timeout); func(…args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } }; document.addEventListener(‘DOMContentLoaded’, async function () { // DOM元素获取 const audio = document.getElementById(‘audio-player’); // 音频播放器元素 const lyricsContainer = document.getElementById(‘lyrics’); // 歌词列表容器 const container = document.getElementById(‘lyrics-container’); // 歌词滚动容器 const toggleBtn = document.getElementById(‘toggle-lyrics’); // 歌词展开/收起按钮 const playBtn = document.getElementById(‘play-btn’); // 播放/暂停按钮 const muteBtn = document.getElementById(‘mute-btn’); // 静音按钮 const progressBar = document.querySelector(‘.progress-bar’); // 进度条容器 const progressFilled = document.querySelector(‘.progress-filled’); // 进度条填充部分 const volumeSlider = document.querySelector(‘.volume-slider’); // 音量滑块 const volumeFilled = document.querySelector(‘.volume-filled’); // 音量填充部分 const currentTimeDisplay = document.querySelector(‘.current-time’); // 当前播放时间显示 const totalTimeDisplay = document.querySelector(‘.total-time’); // 总时长显示 const progressHoverTime = document.querySelector(‘.progress-hover-time’); // 进度条悬停时间提示 const customPlayer = document.querySelector(‘.custom-player’); // 自定义播放器容器 /** * 提取歌词中的歌曲标题并设置为背景 */ function extractAndSetSongTitle(lrcText) { // 尝试从歌词文件的元信息中提取标题 const titleMatch = lrcText.match(/^\[ti:(.*?)\]/mi); // 匹配[ti:标题]格式 const artistMatch = lrcText.match(/^\[ar:(.*?)\]/mi); // 匹配[ar:艺术家]格式 let songTitle = ”; if (titleMatch) { if (titleMatch[1]) { if (artistMatch) { if (artistMatch[1]) { songTitle = `${artistMatch[1].trim()} – ${titleMatch[1].trim()}`; } } else { songTitle = titleMatch[1].trim(); } } } // 如果没有找到标题标签,尝试从第一行非时间戳内容中提取 if (!songTitle) { const firstLineMatch = lrcText.match(/^\[.*?\](.*?)$/m); if (firstLineMatch) { if (firstLineMatch[1]) { songTitle = firstLineMatch[1].trim(); } } } if (songTitle) { const backgroundTitle = document.createElement(‘div’); backgroundTitle.className = ‘player-background-title’; backgroundTitle.innerHTML = `${songTitle}`; // 移除已存在的背景标题(如果有) const existingTitle = customPlayer.querySelector(‘.player-background-title’); if (existingTitle) { existingTitle.remove(); } customPlayer.appendChild(backgroundTitle); } } // 根据配置初始化歌词容器状态 if (CONFIG.lyricsDefaultCollapsed) { container.classList.add(‘collapsed’); toggleBtn.classList.add(‘collapsed’); toggleBtn.querySelector(‘.toggle-text’).textContent = ‘展开歌词’; } // 根据配置控制歌词切换按钮的显示 if (!CONFIG.lyricsToggleable) { toggleBtn.style.display = ‘none’; } // 设置音频源 audio.src = AUDIO_URL; // 状态变量 let currentIndex = 0; // 当前播放的歌词索引 let lyrics = []; // 解析后的歌词数组 let isUserScrolling = false; // 用户是否正在手动滚动歌词 let scrollTimeout; // 滚动超时定时器 let isLyricsCollapsed = CONFIG.lyricsDefaultCollapsed; // 歌词是否处于折叠状态 let currentLyricElement = null; // 当前高亮显示的歌词元素 /** * 处理歌词折叠/展开的切换 */ toggleBtn.addEventListener(‘click’, function() { if (!CONFIG.lyricsToggleable) return; if (!isLyricsCollapsed) { // 折叠歌词 isLyricsCollapsed = true; container.classList.add(‘collapsed’); toggleBtn.classList.add(‘collapsed’); toggleBtn.querySelector(‘.toggle-text’).textContent = ‘展开歌词’; // 隐藏所有歌词,只显示当前播放的歌词 document.querySelectorAll(‘#lyrics li’).forEach(li => { li.style.display = ‘none’; }); if (currentLyricElement) { currentLyricElement.style.display = ‘block’; // 设置折叠状态下的样式 currentLyricElement.style.backgroundColor = ‘transparent’; currentLyricElement.style.color = ‘#d9534f’; currentLyricElement.style.fontWeight = ‘bold’; currentLyricElement.style.fontSize = ‘1.1em’; currentLyricElement.style.transform = ‘translateX(5px)’; // 检查是否有对应的翻译行并应用样式 const currentIndex = Array.from(document.querySelectorAll(‘#lyrics li’)).indexOf(currentLyricElement); if (currentIndex >= 0) { if (lyrics[currentIndex]) { if (lyrics[currentIndex].isOriginal) { if (currentIndex { li.style.display = ”; // 重置样式 li.style.transform = ”; li.style.backgroundColor = ”; li.style.color = ”; li.style.fontWeight = ”; li.style.fontSize = ”; // 恢复原始文本 if (lyrics[index]) { li.textContent = lyrics[index].text; } }); // 重新应用当前歌词的高亮样式 if (currentLyricElement) { currentLyricElement.classList.add(‘active’); // 如果有翻译,同时高亮显示翻译 const currentIndex = Array.from(document.querySelectorAll(‘#lyrics li’)).indexOf(currentLyricElement); if (currentIndex >= 0) { if (lyrics[currentIndex]) { if (lyrics[currentIndex].isOriginal) { if (currentIndex = 0) { if (lyrics[currentIndex]) { if (lyrics[currentIndex].isOriginal) { if (currentIndex { scrollToLyricWithTranslation(currentIndex, hasTranslation); }, 0); } } }); // 显示加载提示 lyricsContainer.innerHTML = ‘
    正在加载歌词…
    ‘; try { // 从服务器获取歌词 const lrcText = await fetchLyrics(LYRICS_URL); // 解析歌词 parseLRC(lrcText); // 添加操作提示 if (lyrics.length > 0) { const playPrompt = document.createElement(‘div’); playPrompt.className = ‘play-prompt’; playPrompt.textContent = ‘点击歌词可跳转到对应的时间点’; container.insertAdjacentElement(‘afterbegin’, playPrompt); // 3秒后淡出提示 setTimeout(() => { playPrompt.classList.add(‘fade-out’); setTimeout(() => playPrompt.remove(), 1000); }, 3000); } } catch (error) { lyricsContainer.innerHTML = ‘
    歌词加载失败,请刷新重试
    ‘; console.error(‘歌词加载错误:’, error); } /** * 从服务器获取歌词文件 * @param {string} url – 歌词文件的URL * @returns {Promise} 歌词文本内容 */ async function fetchLyrics(url) { const response = await fetch(url); if (!response.ok) { throw new Error(`无法获取歌词文件 (状态码: ${response.status})`); } return response.text(); } /** * 解析LRC格式的歌词文本 * @param {string} lrcText – LRC格式的歌词文本 */ function parseLRC(lrcText) { const lines = lrcText.split(‘\n’); // 提取并设置歌曲标题 extractAndSetSongTitle(lrcText); // 检测是否为双语歌词 let isBilingual = false; for (let i = 0; i < lines.length – 1; i++) { const currentTimeMatch = lines[i].match(/\[(\d{2}):(\d{2})\.(\d{1,2})\]/); if (currentTimeMatch) { const nextTimeMatch = lines[i + 1].match(/\[(\d{2}):(\d{2})\.(\d{1,2})\]/); if (nextTimeMatch) { const currentTime = Utils.parseTimestamp(currentTimeMatch); const nextTime = Utils.parseTimestamp(nextTimeMatch); // 如果两行歌词时间戳相同(误差<0.01秒),则认为是双语歌词 if (Math.abs(currentTime – nextTime) { const timeMatch = line.match(/\[(\d{2}):(\d{2})\.(\d{1,2})\]/); if (timeMatch) { const timeInSeconds = Utils.parseTimestamp(timeMatch); const lyricText = line.replace(/\[.*?\]/g, ”).trim(); if (lyricText) return { time: timeInSeconds, text: lyricText }; } return null; }).filter(item => item !== null); // 标记双语歌词 if (isBilingual) { for (let i = 0; i < lyrics.length – 1; i++) { if (Math.abs(lyrics[i].time – lyrics[i + 1].time) < 0.01) { lyrics[i].isOriginal = true; // 原文 lyrics[i + 1].isTranslation = true; // 译文 } } } // 渲染歌词到页面 renderLyrics(); } /** * 将解析后的歌词渲染到页面 */ function renderLyrics() { if (lyrics.length === 0) { lyricsContainer.innerHTML = '
    未找到歌词
    ‘; return; } lyricsContainer.innerHTML = ”; const fragment = document.createDocumentFragment(); lyrics.forEach((lyric, index) => { const li = document.createElement(‘li’); li.textContent = lyric.text; li.dataset.time = lyric.time.toString(); // 添加原文/译文样式类 if (lyric.isOriginal) li.classList.add(‘original’); if (lyric.isTranslation) li.classList.add(‘translation’); // 点击歌词跳转到对应时间点 li.addEventListener(‘click’, () => { audio.currentTime = lyric.time; // 如果当前是暂停状态,则开始播放 if (audio.paused) { audio.play().catch(e => console.warn(‘自动播放失败:’, e)); } updateActiveLyric(index); }); fragment.appendChild(li); }); lyricsContainer.appendChild(fragment); } /** * 更新当前播放歌词的高亮状态 * @param {number} index – 当前歌词的索引 */ function updateActiveLyric(index) { // 移除所有歌词的高亮样式 document.querySelectorAll(‘#lyrics li’).forEach((li, i) => { li.classList.remove(‘active’, ‘active-translation’); li.style.display = isLyricsCollapsed ? ‘none’ : ”; // 重置样式 li.style.backgroundColor = ”; li.style.color = ”; li.style.fontWeight = ”; li.style.fontSize = ”; li.style.transform = ”; // 恢复原始文本 if (lyrics[i]) { li.textContent = lyrics[i].text; } }); const lines = document.querySelectorAll(‘#lyrics li’); const currentLine = lines[index]; if (!currentLine) return; // 更新当前歌词元素引用 currentLyricElement = currentLine; // 高亮显示当前行 currentLine.classList.add(‘active’); currentLine.style.display = ‘block’; // 确定是否有对应的翻译行 let translationLine = null; let translationText = ”; // 检查是否有对应的翻译行 if (lyrics[index]) { if (lyrics[index].isOriginal) { if (index < lyrics.length – 1) { if (lyrics[index + 1].isTranslation) { translationLine = lines[index + 1]; translationText = lyrics[index + 1].text; if (!isLyricsCollapsed) { translationLine.classList.add('active-translation'); translationLine.style.display = 'block'; } } } } } // 如果不是用户手动滚动,则自动滚动到当前歌词 if (!isUserScrolling) { if (!isLyricsCollapsed) { // 展开状态下的滚动逻辑 scrollToLyricWithTranslation(index, translationLine ? true : false); } else { // 折叠状态下的样式 currentLine.style.backgroundColor = 'transparent'; currentLine.style.color = '#d9534f'; currentLine.style.fontWeight = 'bold'; currentLine.style.fontSize = '1.1em'; currentLine.style.transform = 'translateX(5px)'; // 在折叠状态下拼接显示原文和翻译 if (translationText) { // 创建原文和译文的span元素 const originalSpan = document.createElement('span'); originalSpan.textContent = lyrics[index].text; const separatorSpan = document.createElement('span'); separatorSpan.textContent = ' | '; separatorSpan.style.color = '#666'; separatorSpan.style.fontWeight = 'normal'; const translationSpan = document.createElement('span'); translationSpan.textContent = translationText; translationSpan.style.color = 'var(–translation-color)'; translationSpan.style.fontStyle = 'italic'; translationSpan.style.fontSize = '0.95em'; // 清空当前行内容并添加新元素 currentLine.textContent = ''; currentLine.appendChild(originalSpan); currentLine.appendChild(separatorSpan); currentLine.appendChild(translationSpan); } } } } /** * 滚动到指定的歌词行,考虑翻译行 * @param {number} index – 歌词索引 * @param {boolean} hasTranslation – 是否有对应的翻译行 */ function scrollToLyricWithTranslation(index, hasTranslation) { const line = document.querySelectorAll('#lyrics li')[index]; if (!line) return; const offsetTop = line.offsetTop; const containerHeight = container.offsetHeight; // 计算滚动目标位置 // 如果有翻译行,考虑额外的空间以确保翻译行也可见 const additionalSpace = hasTranslation ? line.offsetHeight : 0; const scrollTarget = Math.max(0, offsetTop – containerHeight / 3 – additionalSpace); container.scrollTo({ top: scrollTarget, behavior: 'smooth' }); } /** * 同步音频播放时间和歌词显示 * @param {number} currentTime – 当前播放时间(秒) */ function synchronizeLyricsWithAudio(currentTime) { let foundIndex = -1; // 查找当前时间对应的歌词 for (let i = 0; i < lyrics.length; i++) { if (lyrics[i].time 0) { if (lyrics[i – 1].isOriginal) { foundIndex = i – 1; // 设置为原文索引 } } } else { foundIndex = i; // 否则使用当前索引 } } else { // 一旦找到时间戳大于当前时间的歌词,就停止循环 break; } } // 如果找到对应的歌词且索引发生变化,则更新显示 if (foundIndex >= 0) { if (foundIndex !== currentIndex) { currentIndex = foundIndex; updateActiveLyric(currentIndex); } } } // 音频播放相关事件监听 audio.addEventListener(‘timeupdate’, function() { synchronizeLyricsWithAudio(audio.currentTime); }); audio.addEventListener(‘play’, function() { container.classList.add(‘playing’); customPlayer.classList.add(‘playing’); }); audio.addEventListener(‘pause’, function() { container.classList.remove(‘playing’); customPlayer.classList.remove(‘playing’); }); audio.addEventListener(‘ended’, function() { document.querySelectorAll(‘#lyrics li’).forEach(li => { li.classList.remove(‘active’, ‘active-translation’); }); currentIndex = 0; }); // 歌词容器滚动事件处理 container.addEventListener(‘scroll’, function() { isUserScrolling = true; clearTimeout(scrollTimeout); // 800ms后恢复自动滚动 scrollTimeout = setTimeout(() => { isUserScrolling = false; }, 800); }); // 保持波浪动画效果 container.classList.add(‘playing’); // 播放控制相关函数 function togglePlay() { if (audio.paused) { audio.play(); } else { audio.pause(); } } // 更新进度条显示 function updateProgress() { const percent = (audio.currentTime / audio.duration) * 100; progressFilled.style.width = `${percent}%`; currentTimeDisplay.textContent = Utils.formatTime(audio.currentTime); } // 进度条点击跳转 function scrub(e) { const scrubTime = (e.offsetX / progressBar.offsetWidth) * audio.duration; audio.currentTime = scrubTime; } // 显示进度条悬停时间 function showHoverTime(e) { const hoverTime = (e.offsetX / progressBar.offsetWidth) * audio.duration; progressHoverTime.textContent = Utils.formatTime(hoverTime); progressHoverTime.style.display = ‘block’; progressHoverTime.style.left = `${e.offsetX}px`; } // 音量控制相关函数 function toggleMute() { audio.muted = !audio.muted; updateVolumeIcon(); } function changeVolume(e) { const newVolume = e.offsetX / volumeSlider.offsetWidth; audio.volume = Math.max(0, Math.min(1, newVolume)); volumeFilled.style.width = `${audio.volume * 100}%`; updateVolumeIcon(); } // 更新音量图标状态 function updateVolumeIcon() { const volumeIcon = muteBtn.querySelector(‘.volume-icon’); volumeIcon.className = ‘volume-icon’; if (audio.muted || audio.volume === 0) { volumeIcon.classList.add(‘volume-state-off’); } else if (audio.volume < 0.3) { volumeIcon.classList.add('volume-state-muted'); } else if (audio.volume { totalTimeDisplay.textContent = Utils.formatTime(audio.duration); }); progressBar.addEventListener(‘click’, scrub); progressBar.addEventListener(‘mousemove’, showHoverTime); progressBar.addEventListener(‘mouseout’, () => progressHoverTime.style.display = ‘none’); muteBtn.addEventListener(‘click’, toggleMute); volumeSlider.addEventListener(‘click’, changeVolume); // 初始化音量图标 updateVolumeIcon(); }); /* CSS全局变量定义 */ :root { –primary-color: #87CEEB; /* 主题色(天蓝色) */ –active-color: #d9534f; /* 激活状态颜色(红色) */ –translation-color: #337ab7; /* 翻译文本颜色(蓝色) */ –background-color: #f3f3f3; /* 背景色(浅灰色) */ –text-color: #555; /* 主要文本颜色 */ –text-secondary: #666; /* 次要文本颜色 */ –waves-opacity: 0.6; /* 波浪动画透明度 */ –border-radius: 8px; /* 通用圆角大小 */ –shadow-color: rgba(0,0,0,0.1); /* 阴影颜色 */ } /* 播放器主容器样式 */ .music-player-container { max-width: 100%; /* 最大宽度限制 */ margin: 0 auto; /* 水平居中 */ position: relative; /* 相对定位,作为子元素定位参考 */ background: transparent; /* 透明背景 */ padding: 5px; /* 内边距 */ border-radius: var(–border-radius); /* 圆角边框 */ width: 100%; /* 占满容器宽度 */ box-sizing: border-box; /* 边框盒模型 */ } /* 波浪动画区域样式 */ .waves-area { position: absolute; /* 绝对定位 */ left: 0; right: 0; bottom: 0; height: 100%; /* 占满容器高度 */ z-index: 0; /* 层级设置 */ overflow: hidden; /* 隐藏溢出内容 */ border-radius: var(–border-radius); /* 圆角边框 */ pointer-events: none; /* 禁用鼠标事件 */ } /* 波浪SVG样式 */ .waves-svg { width: 100%; height: 80%; transform: none; position: absolute; bottom: 0; } /* 波浪动画效果 */ .parallax > use { animation: move-forever 25s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite; } /* 多层波浪动画配置 */ .parallax > use:nth-child(1) { animation-delay: -2s; animation-duration: 7s; fill: rgba(135, 206, 235, var(–waves-opacity)); } .parallax > use:nth-child(2) { animation-delay: -3s; animation-duration: 10s; fill: rgba(135, 206, 235, calc(var(–waves-opacity) * 0.75)); } .parallax > use:nth-child(3) { animation-delay: -4s; animation-duration: 13s; fill: rgba(135, 206, 235, calc(var(–waves-opacity) * 0.5)); } .parallax > use:nth-child(4) { animation-delay: -5s; animation-duration: 20s; fill: rgba(135, 206, 235, calc(var(–waves-opacity) * 0.33)); } /* 波浪移动动画关键帧 */ @keyframes move-forever { 0% { transform: translate3d(-90px, 0, 0); } 100% { transform: translate3d(85px, 0, 0); } } /* 自定义播放器样式 */ .custom-player { position: relative; width: 100%; border-radius: var(–border-radius); margin-bottom: 8px; box-shadow: 0 2px 8px rgba(135, 206, 235, 0.2); background: rgba(255, 255, 255, 0.7); padding: 8px 12px; box-sizing: border-box; overflow: hidden; } /* 播放器背景标题样式 */ .player-background-title { position: absolute; left: 52px; top: 3px; font-size: 11px; font-weight: 400; white-space: nowrap; pointer-events: none; z-index: 0; font-family: “PingFang SC”, “Microsoft YaHei”, “Hiragino Sans GB”, “Noto Sans SC”, “Source Han Sans CN”, sans-serif; letter-spacing: 1px; opacity: 0.9; transform: scale(0.9); transform-origin: left top; } .player-background-title span { color: rgba(100, 180, 220, 0.75); } /* 播放器控制区域样式 */ .player-controls { position: relative; z-index: 1; display: flex; align-items: center; gap: 12px; height: 32px; max-width: 100%; } /* 播放/暂停按钮样式 */ #play-btn { width: 32px; height: 32px; border: none; border-radius: 50%; background: var(–primary-color); cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; transition: all 0.3s ease; } /* 播放按钮悬停效果 */ #play-btn:hover { background: #5CACEE; transform: scale(1.05); } /* 播放按钮图标样式 */ #play-btn svg { width: 20px; height: 20px; fill: white; } /* 播放/暂停图标切换 */ .pause-icon { display: none; } .playing .play-icon { display: none; } .playing .pause-icon { display: block; } /* 进度条容器样式 */ .progress-container { flex: 1; position: relative; min-width: 0; } /* 进度条基础样式 */ .progress-bar { height: 3px; background: rgba(135, 206, 235, 0.2); border-radius: 1.5px; cursor: pointer; position: relative; } /* 进度条填充部分样式 */ .progress-filled { height: 100%; background: var(–primary-color); border-radius: 1.5px; width: 0%; position: relative; transition: width 0.1s ease-in-out; } /* 进度条拖动点样式 */ .progress-filled::after { content: ”; position: absolute; right: -5px; top: -3.5px; width: 10px; height: 10px; background: var(–primary-color); border: 2px solid white; border-radius: 50%; box-shadow: 0 1px 3px var(–shadow-color); opacity: 0; transition: opacity 0.2s ease; } /* 进度条悬停时显示拖动点 */ .progress-bar:hover .progress-filled::after { opacity: 1; } /* 进度条时间提示样式 */ .progress-hover-time { position: absolute; top: -25px; background: rgba(0,0,0,0.7); color: white; padding: 2px 6px; border-radius: 4px; font-size: 12px; transform: translateX(-50%); display: none; } /* 时间显示样式 */ .time-display { font-size: 12px; color: var(–text-secondary); min-width: 85px; text-align: center; white-space: nowrap; } .time-separator { margin: 0 4px; opacity: 0.5; } /* 音量控制区域样式 */ .volume-control { display: flex; align-items: center; gap: 8px; position: relative; min-width: 120px; } /* 静音按钮样式 */ #mute-btn { width: 32px; height: 32px; border: none; background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; } /* 音量图标样式 */ #mute-btn svg { width: 20px; height: 20px; fill: var(–primary-color); } /* 音量滑块容器样式 */ .volume-slider-container { width: 80px; position: relative; } /* 音量滑块基础样式 */ .volume-slider { height: 3px; background: rgba(135, 206, 235, 0.2); border-radius: 1.5px; cursor: pointer; position: relative; } /* 音量滑块填充部分样式 */ .volume-filled { height: 100%; background: var(–primary-color); border-radius: 1.5px; width: 100%; position: relative; } /* 音量滑块拖动点样式 */ .volume-filled::after { content: ”; position: absolute; right: -6px; top: -4px; width: 12px; height: 12px; background: var(–primary-color); border: 2px solid white; border-radius: 50%; box-shadow: 0 1px 3px var(–shadow-color); opacity: 0; transition: opacity 0.2s ease; } /* 音量滑块悬停时显示拖动点 */ .volume-slider:hover .volume-filled::after { opacity: 1; } /* 音量图标状态样式 */ .volume-icon path { display: none; } .volume-state-high .volume-high, .volume-state-low .volume-low, .volume-state-muted .volume-muted, .volume-state-off .volume-off { display: block; } /* 歌词容器包装样式 */ .lyrics-container-wrapper { position: relative; border-radius: var(–border-radius); overflow: hidden; } /* 歌词滚动容器样式 */ .lyrics-scroll-container { position: relative; z-index: 1; overflow-y: auto; max-height: 350px; border-radius: var(–border-radius); box-shadow: 0 2px 8px var(–shadow-color); scroll-behavior: smooth; background: rgba(255, 255, 255, 0.7); transition: all 0.3s ease; } /* 歌词折叠状态样式 */ .lyrics-scroll-container.collapsed { max-height: 36px; overflow: hidden; } .lyrics-scroll-container.collapsed #lyrics li { text-align: center; margin: 0; padding: 8px 0; line-height: 20px; } /* 歌词折叠按钮样式 */ .toggle-lyrics-btn { position: absolute; top: 2px; right: 10px; z-index: 3; background: rgba(255, 255, 255, 0.9); border: 1px solid rgba(135, 206, 235, 0.3); border-radius: 15px; padding: 5px 12px; cursor: pointer; display: flex; align-items: center; gap: 5px; font-size: 14px; color: var(–text-secondary); transition: all 0.3s ease; } /* 折叠按钮悬停效果 */ .toggle-lyrics-btn:hover { background: rgba(255, 255, 255, 1); box-shadow: 0 2px 4px var(–shadow-color); } /* 折叠图标动画 */ .toggle-icon { transition: transform 0.3s ease; } .toggle-lyrics-btn.collapsed .toggle-icon { transform: rotate(-90deg); } /* 自定义滚动条样式 */ .lyrics-scroll-container::-webkit-scrollbar { width: 4px; } .lyrics-scroll-container::-webkit-scrollbar-track { background: transparent; } .lyrics-scroll-container::-webkit-scrollbar-thumb { background-color: rgba(135, 206, 235, 0.3); border-radius: 2px; } /* 歌词列表基础样式 */ #lyrics { position: relative; z-index: 2; padding: 0; margin: 0; background: transparent; padding-bottom: 100px; width: 100%; margin: 0 auto; } /* 歌词行样式 */ #lyrics li { list-style: none; padding: 4px 5px; cursor: pointer; transition: all 0.2s ease; border-radius: 4px; margin-bottom: 1px; line-height: 1.5; color: var(–text-color); text-align: center; width: 100%; } /* 歌词行悬停效果 */ #lyrics li:hover { background-color: rgba(0,0,0,0.05); } /* 当前播放歌词样式 */ #lyrics li.active { color: var(–active-color); font-weight: bold; font-size: 1.1em; background-color: rgba(217, 83, 79, 0.1); } /* 当前播放歌词的翻译样式 */ #lyrics li.active-translation { color: var(–translation-color); font-style: italic; background-color: rgba(51, 122, 183, 0.1); } /* 翻译歌词样式 */ #lyrics li.translation { padding-left: 12px; color: var(–text-secondary); font-size: 0.95em; border-left: none; margin-top: -1px; margin-bottom: 4px; text-align: center; } /* 提示消息样式 */ .loading-message, .error-message, .no-lyrics { text-align: center; padding: 20px; color: var(–text-secondary); } .error-message { color: var(–active-color); } /* 播放提示样式 */ .play-prompt { text-align: center; padding: 8px; background-color: rgba(255, 193, 7, 0.2); color: #856404; border-radius: 4px; margin-bottom: 10px; font-size: 14px; transition: opacity 1s ease; } .play-prompt.fade-out { opacity: 0; } /* 响应式布局样式 */ @media (max-width: 768px) { /* 移动端基础样式调整 */ .music-player-container { padding: 2px; } /* 移动端波浪动画高度调整 */ .waves-svg { height: 40px; min-height: 40px; } /* 移动端歌词容器调整 */ .lyrics-scroll-container { max-height: 300px; } /* 移动端歌词列表调整 */ #lyrics { max-width: 100%; } #lyrics li, #lyrics li.translation, .lyrics-scroll-container.collapsed #lyrics li { text-align: left; padding-left: 5px; } /* 移动端控制元素尺寸调整 */ .time-display { min-width: 75px; } .volume-control { min-width: 100px; } .volume-slider-container { width: 60px; } } /* 小屏幕设备样式调整 */ @media (max-width: 480px) { .volume-slider-container { width: 40px; } .time-display { min-width: 70px; } .player-controls { gap: 8px; } } /* 大屏幕设备样式调整 */ @media (min-width: 1200px) { } /* 移动端特定样式 */ @media (max-width: 768px) { /* 移动端歌词高亮效果 */ #lyrics li.active, #lyrics li.active-translation { transform: translateX(5px); } }

    评论

    9 + 4 = ?
    您的邮箱地址不会被公开。必填项已用 * 标注 如遇验证码无法通过,请勿使用无痕/隐私浏览器模式