亚伦影音工作室 发表于 2025-5-7 15:55

多曲多行歌词播放器

本帖最后由 亚伦影音工作室 于 2025-6-26 11:37 编辑 <br /><br /><style>
#bj{position: relative;width: 1186px;height: 680px;LEFT:-300px;top:-120px;overflow:hidden;background:#800 url(https://pic1.imgdb.cn/item/68187d2458cb8da5c8dd7382.jpg)no-repeat center / cover;}
#cd{display: none;}
.song-list-containe {position: absolute;
margin-top: 10%;
margin-left: 70%;
color:#000;
width:400px;
font:400 1.2em/0.1em 仿宋; column-count: 1;
}

.song-list {
list-style: none;
padding: 0;
color: #fff;
overflow-x: hidden;

}

.song-item {
padding: 1rem 1.5rem;
cursor: pointer;
}

.song-item:hover {
color: #00ff00;
}
.song-item.active {
color: #000;
font-weight: 500;
}
.lyrics-container {
position: absolute;
max-height: 250px;
overflow-y: hidden;
overflow-x: hidden;
cursor: pointer;
text-align: center;
MARGIN-LEFT:120px;
margin-top:12%;
font: 500 25px 'FZYaoti', sans-serif;
line-height: 50px;
color: #ccc;
}
.highlight {
color: #000;
padding-left: 0.5rem;
font-size:30px;
}

#bt{ --w: 66%; width: var(--w); overflow: hidden; color: #fff; position: absolute; left:56%;top:88%;font:normal 16px 仿宋;cursor:pointer;}
#bt { word-break: keep-all; white-space: nowrap; animation: bt 23s linear infinite; background:#0000}
@keyframes bt {50% { transform: translateX(calc(0% - var(--w))); }}

#bt:hover {
color: #00ff00;
animation-play-state: paused;
}

#bfq{   
      position:absolute;
      width: 450px;
      height:350px;overflow: hidden;
      background:#0000;
transform:scale(.4);bottom: -100px;
   left: -120px;z-index: 20;}
#cp{   
      position:absolute;
      width: 240px;border-radius: 50%;
      height:240px;animation: rotating 6s infinite linear;
      top:18%;background:repeating-radial-gradient(black, black 5px, #1C1C1C 6px, #1C1C1C 7px);
   cursor: pointer;
   left: 12%;z-index: 1;box-shadow:0px 0px 0px 1px #fff,0px 0px 0px 0px #880000;}
@keyframes rotating { to { transform: rotate(360deg); } }
.overlay {
content: '';
left: 50%;
top: 50%; transform: translate(-50%, -50%);
position: absolute;
width: 238px;
height: 238px;
background: linear-gradient(45deg, transparent, 40%, rgba(255,255,255,0.25), 60%, transparent);
border-radius: 50%;
}


.inner {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
box-shadow:0px 0px 0px 1px #eee,0px 0px 0px 2px #444;
background:#880000 url('') no-repeat center / cover;

border-radius: 50%;
}
.inner::before {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 15px;
height: 15px;
background: #ccc;
border-radius: 50%;
}
#cz {position: absolute;
      top:6%; left:45%;z-index: 2;
      width: 150px;background: url('https://pic1.imgdb.cn/item/6688e0dad9c307b7e9a7a3e1.png')no-repeat center/85%;
      height: 300px;
      cursor: pointer;
}

.pink { transform:rotate(5deg);transform-origin: 100% 0%;}
.purple {transform-origin: 80% 0%;margin: -4px -18px;transform:rotate(-9deg);}
#prog {position: absolute;z-index: 8;
      width: 78%;
      height: 2px;background:#ccc;
      cursor: pointer;
         bottom: 46px;
left:12%;
border-radius: 1px;}
#prog-bar {
            height: 100%;
            background: #FF0000;
            width: 0%;
      }

#tmsg {position: absolute;z-index: 8;
      font: normal 12px sans-serif;
      color: #ffffff;
         bottom: 42px;
      right: 40px;}

#world,#fullscreen {border-radius: 4px;position: relative;background:#0000 ;
color:#fff;box-shadow:0px 0px 0px 1px #fff;
padding: 4px 10px;
font-size: 12px;
border: none;
cursor: pointer;margin: 8px 5px;left: 75%;top: 30px;
}
</style>
<divid="bj">
<div id="bfq">
<div id="cz"class="pink"></div>
<div id="cp"><div class="inner"></div><div class="overlay"></div></div>
</div>
<div id="prog" title="播放进度条"><div id="prog-bar"></div></div>
<div id="tmsg">00:00|00:00</div>
<span id="world" onclick="btncd()"title="歌曲菜单">菜单显示</span>
<span id="fullscreen" title="屏展模式">全屏欣赏</span>

<div id="cd">
<div class="song-list-containe">
<p id="song-list" class="song-list">
</p>
</div>
</div>
<div id="lyrics" class="lyrics-container w-full max-w-4xl">
</div>
<div id="bt"><div>

</div>
<script>

var xmhy = [
["https://img4.oldkids.cn/upload/2025/04/30/blog_260848378_20250430071949509.mp3","凝音 - 致奔波在人生路上的自己",`致奔波在人生路上的自己
作词:晗熙
作曲:阿豪
演唱:凝音
☆★Lrc编辑 梅竹★☆
☆★协编 亚伦★☆
亚伦影音工作室
谁愿意日日 披星戴月
只是生活 它像一个圆圈
我们往复的走 从不停歇
眼中为谁多了坚决
日子虽苦偶尔却有甜
雨过天晴伤痛也会改变
就把遗憾放在 已去的昨天
然后大步向前
致那奔波人生路上的自己
走到如今你用了多大勇气
到底怎样的结局 才配这颠沛流离
我知道你一定不会放弃
致那奔波人生路上的自己
你所有努力值得幸福肯定
就别让心太累了 看看沿途风景
再重新 把一切追寻 天会放晴
亚伦影音工作室
日子虽苦偶尔却有甜
雨过天晴伤痛也会改变
就把遗憾放在 已去的昨天
然后大步向前
致那奔波人生路上的自己
走到如今你用了多大勇气
到底怎样的结局 才配这颠沛流离
我知道你一定不会放弃
致那奔波人生路上的自己
你所有努力值得幸福肯定
就别让心太累了 看看沿途风景
再重新 把一切追寻 天会放晴
致那奔波人生路上的自己
走到如今你用了多大勇气
到底怎样的结局 才配这颠沛流离
我知道你一定不会放弃
致那奔波人生路上的自己
你所有努力值得幸福肯定
就别让心太累了 看看沿途风景
再重新 把一切追寻 天会放晴
(Music)
☆★谢谢欣赏★☆
=End=`],
["https://s2.ananas.chaoxing.com/sv-w9/audio/b2/69/63/67de1f26637fc541b8a39812e378e692/audio.mp3","马健涛 - 手心有你(DJ 版)",`手心有你(DJ 版)
词曲:马健涛
编曲:马健涛
htnl动画设计:亚伦
演唱:马健涛
出品:亚伦影音
歌词制作:亚伦
让我留在你身边多一天
让我爱你每天多一点
让我今生与你做伴
让我亲吻你的脸蛋
我在梦到你的夜里流泪
双手捧着你的相片
你是我放不下的人
我要把你捧在我手心
谢谢你一直的包容我
没有丢下我
谢谢你一直的爱着我
原谅我的过错
感谢上苍把你赐给我
温暖了我心窝
当我哭泣难过的时候
你会紧紧抱着我
让我留在你身边多一天
让我爱你每天多一点
让我今生与你做伴
让我亲吻你的脸蛋
我在梦到你的夜里流泪
双手捧着你的相片
你是我放不下的人
我要把你捧在我手心
谢谢你一直的包容我
没有丢下我
谢谢你一直的爱着我
原谅我的过错
感谢上苍把你赐给我
温暖了我心窝
当我哭泣难过的时候
你会紧紧抱着我
让我留在你身边多一天
让我爱你每天多一点
让我今生与你做伴
让我亲吻你的脸蛋
我在梦到你的夜里流泪
双手捧着你的相片
你是我放不下的人
我要把你捧在我手心
让我留在你身边多一天
让我爱你每天多一点
让我今生与你做伴
让我亲吻你的脸蛋
我在梦到你的夜里流泪
双手捧着你的相片
你是我放不下的人
我要把你捧在我手心
我要把你捧在我手心`]

      ];
      
      const songList = document.getElementById('song-list');
      const audio = document.createElement('audio');
      const lyricsDiv = document.getElementById('lyrics');
      let currentSongIndex = 0;
      let currentLyricIndex = -1;
      
      // 生成曲目列表
      xmhy.forEach((song, index) => {
            const li = document.createElement('li');
            li.className = 'song-item';
            li.textContent = (index + 1) + "." + song;
            li.dataset.index = index;
            li.addEventListener('click', () => selectSong(index));
            songList.appendChild(li);
      });
      
      function selectSong(index) {
            document.querySelectorAll('.song-item').forEach(li => li.classList.remove('active'));
            document.querySelectorAll('.lyric-line').forEach(line => line.classList.remove('highlight'));
            currentLyricIndex = -1;
            bt.innerHTML = '正在播放:' + xmhy.length + '首' + "/" + (index + 1) + "." + xmhy;
            const selectedLi = document.querySelector(``);
            selectedLi.classList.add('active');
            currentSongIndex = index;
            audio.src = xmhy;
            displayLyrics(xmhy);
            audio.play();
            
            window.scrollTo({ top: window.scrollY });
      }
      
      function displayLyrics(lyricsText) {
            lyricsDiv.innerHTML = '';
            const lines = lyricsText.split('\n').map(line => line.trim());
            const lyricList = [];
            
            lines.forEach(line => {
                const timeMatch = line.match(/\[(\d{2}):(\d{2})\.(\d{3})\]/);
                if (timeMatch) {
                  const time = parseFloat(timeMatch) * 60 + parseFloat(timeMatch) + parseFloat(timeMatch) / 1000;
                  const text = line.replace(timeMatch, '').trim();
                  lyricList.push({ time, text });
                } else {
                  const timeMatchTwo = line.match(/\[(\d{2}):(\d{2})\.(\d{2})\]/);
                  if (timeMatchTwo) {
                        const time = parseFloat(timeMatchTwo) * 60 + parseFloat(timeMatchTwo) + parseFloat(timeMatchTwo) / 1000;
                        const text = line.replace(timeMatchTwo, '').trim();
                        lyricList.push({ time, text });
                  }
                }
            });
            
            lyricList.forEach(({ time, text }, index) => {
                const p = document.createElement('p');
                p.className = 'lyric-line';
                p.textContent = text;
                p.dataset.time = time;
                p.dataset.index = index;
                p.addEventListener('click', () => jumpToLyric(index));
                lyricsDiv.appendChild(p);
            });
            
            audio.removeEventListener('timeupdate', updateLyrics);
            audio.addEventListener('timeupdate', updateLyrics);
      }
      
      function updateLyrics() {
            const currentTime = audio.currentTime;
            const lyricLines = Array.from(lyricsDiv.querySelectorAll('.lyric-line'));
            
            const newIndex = lyricLines.findIndex((line, index) => {
                const lineTime = parseFloat(line.dataset.time);
                return lineTime <= currentTime && (lyricLines ? parseFloat(lyricLines.dataset.time) > currentTime : true);
            });
            
            if (newIndex !== currentLyricIndex && newIndex !== -1) {
                lyricLines?.classList.remove('highlight');
                lyricLines.classList.add('highlight');
                currentLyricIndex = newIndex;
               
                // 确保高亮行始终位于第3行
                const lineHeight = 30; // 每行歌词的高度
                const containerHeight = 150; // 歌词容器的高度
                const visibleLines = 5; // 可见的行数
                const highlightLine = 3; // 高亮行的索引(从0开始计数)
               
                lyricsDiv.scrollTo({
                  top: lyricLines.offsetTop - lineHeight * highlightLine,
                  behavior: 'smooth'
                });
            }
      }
      
      function jumpToLyric(index) {
            const targetTime = parseFloat(lyricsDiv.children.dataset.time);
            audio.currentTime = targetTime;
            updateLyrics();
      }
      
      audio.addEventListener('ended', () => {
            currentSongIndex = (currentSongIndex + 1) % xmhy.length;
            selectSong(currentSongIndex);
      });
      
      selectSong(currentSongIndex);
    </script>
   
    <script>
      function btncd() {
            var img = document.getElementById("cd");
            if (document.getElementById("world").innerHTML == "菜单隐藏") {
                img.style.display = 'none';
                document.getElementById("world").innerHTML = "菜单显示";
            } else {
                img.style.display = 'block';
                document.getElementById("world").innerHTML = "菜单隐藏";
            }
      }
      
      let fs = true;
      fullscreen.onclick = () => {
            if (fs) {
                fullscreen.innerText = '退出全屏';
                bj.requestFullscreen();
            } else {
                fullscreen.innerText = '全屏欣赏';
                document.exitFullscreen();
            }
            fs = !fs;
      };
      
      audio.addEventListener('timeupdate', () => {
            tmsg.innerText = toMin(audio.currentTime) + ' | ' + toMin(audio.duration);
      });
      
      function toMin(val) {
            if (!val) return '00:00';
            val = Math.floor(val);
            let min = parseInt(val / 60);
            let sec = parseFloat(val % 60);
            if (min < 10) min = '0' + min;
            if (sec < 10) sec = '0' + sec;
            return min + ':' + sec;
      }
      
      prog.onclick = (e) => { audio.currentTime = audio.duration * e.offsetX / prog.offsetWidth; }
      
      var progBar = document.getElementById('prog-bar');
      audio.addEventListener('timeupdate', () => {
            const percent = (audio.currentTime / audio.duration) * 100;
            progBar.style.width = percent + '%';
      });
      
      cp.onclick = cz.onclick = () => audio.paused ? (audio.play(), cz.classList.remove('purple'),vid.play()) : (audio.pause(), cz.classList.add('purple'),vid.pause());
      
      cp.style.animationPlayState = audio.paused ? 'paused' : 'running';
      audio.addEventListener('playing', () => cp.style.animationPlayState = 'running');
      audio.addEventListener('pause', () => cp.style.animationPlayState = 'paused');
      
      bt.style.animationPlayState = audio.paused ? 'paused' : 'running';
      audio.addEventListener('playing', () => bt.style.animationPlayState = 'running');
      audio.addEventListener('pause', () => bt.style.animationPlayState = 'paused');
      
      document.querySelectorAll('.lyric-line').forEach(line => {
            line.addEventListener('click', event => {
                event.preventDefault();
                event.stopPropagation();
            });
      });
    </script>

亚伦影音工作室 发表于 2025-5-7 16:00

上下乱跳,歌词动画面也动,请马老修改!

红影 发表于 2025-5-7 17:25

没法回帖,直接跳走了{:4_203:}

杨帆 发表于 2025-5-7 21:45

总体构思很棒,亚伦老师辛苦了{:4_191:}
页: [1]
查看完整版本: 多曲多行歌词播放器