|
|

楼主 |
发表于 2023-2-19 08:51
|
显示全部楼层
代码
- <style>
- #papa {
- margin: auto;
- padding: 20px;
- width: 700px;
- height: 400px;
- box-shadow: 3px 3px 20px #000;
- position: relative;
- }
- #lrc {
- --motion: cover2;
- --tt: 2s;
- --state: paused;
- --bg: linear-gradient(180deg, hsla(60, 50%, 50%, .45), hsla(80, 70%, 50%, .65));
- position: absolute;
- font: bold 2em sans-serif;
- color: snow;
- white-space: pre;
- -webkit-background-clip: text;
- filter: drop-shadow(1px 1px 2px hsla(0, 0%, 0%, .95));
- }
- #lrc::before {
- position: absolute;
- content: attr(data-lrc);
- width: 20%;
- height: 100%;
- color: transparent;
- overflow: hidden;
- white-space: pre;
- background: var(--bg);
- filter: inherit;
- -webkit-background-clip: text;
- animation: var(--motion) var(--tt) linear forwards;
- animation-play-state: var(--state);
- }
- @keyframes cover1 { from { width: 0; } to { width: 100%; } }
- @keyframes cover2 { from { width: 0; } to { width: 100%; } }
- @keyframes rot { to { transform: rotate(1turn); } }
- </style>
- <div id="papa">
- <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2022397273.mp3" controls loop autoplay></audio>
- <div id="lrc" data-lrc="HCPlayer">HCPlayer</div>
- </div>
- <script>
- /*原始lrc歌词*/
- let lrcStr = `
- [00:02.00]邹沛沛 - 爱如火(浪漫版)
- [00:18.07]Oh Na na na yeah Ah oh
- [00:24.35]心在跳 是爱情如烈火
- [00:29.07]你在笑 疯狂的人是我
- [00:34.79]爱如火 会温暖了心窝
- [00:39.61]我看见 爱的火焰闪烁
- [00:45.45]从第一刻见到你
- [00:48.59]哦我的心在怦怦跳
- [00:51.86]刻板标准都不重要
- [00:54.98]自你闯入我瞳孔
- [00:58.78]蝴蝶拥着火微笑
- [01:01.26]时间暂停掉
- [01:03.81]你说的每个字
- [01:05.95]我都牢记在心头
- [01:08.56]见面的每一次
- [01:10.72]都有不同的心动
- [01:13.34]我只想一辈子
- [01:15.52]都有你牵我的手
- [01:18.06]走到很久以后
- [01:20.03]Oh my baby
- [01:22.94]心在跳 是爱情如烈火
- [01:27.42]你在笑 疯狂的人是我
- [01:32.35]爱如火 会温暖了心窝
- [01:36.06]我看见 爱的火焰闪烁
- [01:42.27]Na na na na na na yeah
- [01:46.15]Woo woo
- [01:48.02]爱的火焰闪烁
- [01:52.95]Na na na na na na yeah
- [01:56.17]Woo woo my baby
- `;
- /*变量 :mKey - 当前歌词索引;mFlag :调用关键帧动画索引*/
- let mKey = 0, mFlag = true;
- /*函数 :获取每句歌词用时,歌词用时若超过平均值则取平均值,最后一句歌词则取平均值*/
- let lrcTime = (ar) => {
- let tmpAr = [];
- for(j = 0; j <ar.length - 1; j ++) {
- if(j !== ar.length - 1) tmpAr[j] = parseFloat((ar[j+1][0] - ar[j][0]).toFixed(1));
- }
- let aver = parseInt(tmpAr.reduce((a,b) => a + b) / (tmpAr.length - 1));
- tmpAr.push(aver);
- tmpAr.forEach((item,key) => {
- ar[key][2] = item > aver ? aver : item;
- });
- return ar;
- };
- /*函数 :从原始lrc歌词获取信息并存入 n*3 数组*/
- let getLrcAr = (text) => {
- let lrcAr = [];
- let calcRule = [60,1,0.001];
- for(x of text.split('\n')) {
- let ar = [];
- let re = /\d+[\.:]\d+([\.:]\d+)?/g;
- let geci = x.replace(re,'');
- if(geci) {
- geci = geci.replace(/[\[\]\'"\t,]s?/g,'');
- let time = x.match(re);
- if(time != null) {
- for(y of time) {
- let tmp = y.match(/\d+/g);
- let sec = 0;
- for(z in tmp) sec += tmp[z] * calcRule[z];
- ar[0] = [parseFloat(sec.toFixed(2)), geci];
- lrcAr.push(ar[0]);
- }
- }
- }
- }
- lrcAr.sort((a,b)=> a[0] - b[0]);
- return(lrcTime(lrcAr));
- };
- /*函数 :模拟显示同步歌词*/
- let showLrc = (time) => {
- let name = mFlag ? 'cover1' : 'cover2';
- lrc.innerHTML = lrcAr[mKey][1];
- lrc.dataset.lrc = lrcAr[mKey][1];
- lrc.style.setProperty('--motion', name);
- lrc.style.setProperty('--tt', time + 's');
- lrc.style.setProperty('--state', 'running');
- mKey += 1;
- mFlag = !mFlag;
- };
- /*函数 :处理当前歌词索引 mKey*/
- let calcKey = () => {
- for (j = 0; j < lrcAr.length; j++) {
- if (aud.currentTime <= lrcAr[j][0]) {
- mKey = j - 1;
- break;
- }
- }
- if (mKey < 0) mKey = 0;
- if (mKey > lrcAr.length - 1) mKey = lrcAr.length - 1;
- let time = lrcAr[mKey][2] - (aud.currentTime - lrcAr[mKey][0]);
- showLrc(time);
- };
- /*格式化时间信息*/
- let toMin = (val) => {
- if (!val) return '00:00';
- val = Math.floor(val);
- let min = parseInt(val / 60),
- sec = parseFloat(val % 60);
- if (min < 10) min = '0' + min;
- if (sec < 10) sec = '0' + sec;
- return min + ':' + sec;
- }
- /*函数 :歌词同步状态切换*/
- let mState = () => lrc.style.setProperty('--state', aud.paused ? 'paused' : 'running');
- /*监听播放进度*/
- aud.addEventListener('timeupdate', () => {
- for (j = 0; j < lrcAr.length; j++) {
- if (aud.currentTime >= lrcAr[j][0]) {
- cKey = j;
- if (mKey === j) showLrc(lrcAr[j][2]);
- else continue;
- }
- }
- });
- aud.addEventListener('pause', () => mState());/*监听暂停事件*/
- aud.addEventListener('play', () => mState());/*监听播放事件*/
- aud.addEventListener('seeked', () => calcKey());/*监听查询事件*/
- let lrcAr = getLrcAr(lrcStr); /*获得歌词数组*/
- </script>
复制代码
|
|