|
|

楼主 |
发表于 2023-2-18 20:30
|
显示全部楼层
代码
- <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=2015286363.mp3" controls loop autoplay></audio>
- <div id="lrc" data-lrc="HCPlayer">HCPlayer</div>
- </div>
- <script>
- /*原始lrc歌词*/
- let lrcStr = `
- [00:02.00]韩红 - 望
- [00:12.27]长风落进斜阳
- [00:18.24]悲歌多断肠
- [00:24.06]一卷天下涛与浪
- [00:30.97]惊魂破绝然踏蹄扬
- [00:36.88]燃尽卑微的我
- [00:42.79]无声轻轻坠落
- [00:48.94]怀一腔血赤胆忠良
- [00:54.55]撑一撑就到天亮
- [00:59.99]迢迢归乡之路
- [01:05.90]孤单伴着满足
- [01:11.31]曾几时梦里
- [01:14.28]遇见过你
- [01:17.13]就此别过亦是幸福
- [01:23.10]遥遥壮烈时刻
- [01:29.89]幸得慷慨一搏
- [01:35.98]不畏浮云遮望眼
- [01:41.83]何惧世间起浓烟
- [01:47.06]唱一生忠义
- [01:52.68]颂英雄之躯
- [01:58.53]蓦然间回首
- [02:01.29]收紧了心头
- [02:04.41]听那首人间悲曲
- [02:10.50]一曲悲歌
- [02:13.29]一世离合
- [02:16.23]皆化作山河
- [02:22.05]一曲悲歌
- [02:25.02]一世离合
- [02:28.08]仰天长啸一首歌
- [02:32:99]感谢欣赏
- `;
- /*变量 :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*2 数组*/
- let getLrcAr = (str) => {
- str = str.trim();
- let lines = [], lrcAr = [];
- let reg = /\[(\d{1,}:\d{1,}.\d{1,})\](.*)/g;
- if(!str.match(reg)) return;
- lines = str.replace(reg,'$1-{}-$2').split('\n');
- for(k = 0; k < lines.length; k ++) {
- lrcAr[k] = [];
- for(j = 0; j < 3; j ++) {
- let tmpAr = lines[k].split('-{}-');
- lrcAr[k][j] = j === 0 ? toSecs(tmpAr[0]) : tmpAr[1];
- }
- }
- return lrcTime(lrcAr); /* 数组变为 n*3 */
- };
- /*函数 :原始lrc时间转为秒数*/
- let toSecs = (lrcTime) => {
- let reg = /\d{2,}/g;
- let ar = lrcTime.match(reg);
- return ar[0]*60 + parseInt(ar[1]) + parseInt((ar[2])/1000);
- };
- /*函数 :模拟显示同步歌词*/
- 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>
复制代码
|
|