<style> |
| #papa { margin: 150px 0 20px calc(50% - 621px); background:#800 url(' ')no-repeat center/cover;width: 1050px; height: 590px; box-shadow: 3px 3px 6px gray; overflow: hidden; z-index: 1; position: relative; display: grid; place-items: center; } |
| |
| #mdiv {z-index: 10; |
| --size: 0px; |
| --color: teal; |
| position: relative; |
| left: calc(-35% - var(--size) / 2); |
| top: 230px; |
| width: var(--size); |
| height: var(--size); |
| display: grid; |
| place-items: center; |
| animation: rot 8s linear infinite ; |
| cursor: pointer; |
| } |
| #mdiv::before, #mdiv::after { |
| position: absolute; |
| content: ''; |
| width: 0; |
| height: 0; |
| border-style: solid; |
| border-width: calc(var(--size) / 2) calc(var(--size) / 2 - 35px); |
| border-color: var(--color) transparent; |
| |
| border-radius: 100% 100% 100% 100%; |
| filter:drop-shadow(#000 1px 0 0)drop-shadow(#000 0 1px 0)drop-shadow(#000 -1px 0 0) drop-shadow(#000 0 -1px 0); |
| } |
| #mdiv::after { transform: rotate(90deg) } |
| @keyframes rot { 100% { transform: rotate(360deg);filter:hue-rotate(360deg); } } |
| |
| #vid {z-index: 2; |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| -webkit-mask-image: radial-gradient(black 10% ,transparent 90%); |
| } |
| #vido {z-index: 1; |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| } |
| |
| #fullscreen { position: absolute; top: 30px; right:30px;font: normal 2em/0em 楷体;color:#000; opacity: 1; cursor: pointer; z-index: 111} |
| </style> |
| <div id="papa"> |
| <div id="mdiv" title=""></div> |
| <div data-lrc=" " id="lrc" title="歌词显示"> </div> |
| <span id="fullscreen">全屏欣赏</span> |
| <audio id="aud" src="https://music.163.com/song/media/outer/url?id=395611.mp3" autoplay loop></audio> |
| <video id="vid" src="" autoplay loop muted></video> |
| <video id="vido" src="[url]https://file.uhsea.com/2506/fd77857fd6feb698ea5640d4d7d7c3e3GB.mp4[/url]" autoplay loop muted></video> |
| </div> |
| |
| |
| |
| <script> |
| mdiv.onclick = () => aud.paused ?( aud.play(),vid.play(),vido.play()):(aud.pause(),vid.pause(),vido.pause()); |
| mdiv.style.animationPlayState = aud.paused ? 'paused' : 'running'; |
| aud.addEventListener('playing', () =>mdiv.style.animationPlayState = 'running'); |
| aud.addEventListener('pause', () =>mdiv.style.animationPlayState = 'paused'); |
| |
| let fs = true; |
| fullscreen.onclick = () => { |
| fs ? (fullscreen.innerText = '退出全屏', papa.requestFullscreen()) : (fullscreen.innerText = '全屏欣赏', document.exitFullscreen()); |
| fs = !fs; |
| }; |
| |
| </script> |
| <style type="text/css"> |
| #lrc {--state: paused;--motion: cover2;--tt: 2s;--bg: linear-gradient(0deg, #880000, #880000, #880000); |
| position: absolute;z-index: 6;left: 50%; top: 85%;transform: translate(-50%);font:normal 2em 华文新魏; font-weight:400;color: #000080;white-space: pre;-webkit-background-clip: text;filter:drop-shadow(#FFFFFF 1px 0 0)drop-shadow(#FFFFFF 0 1px 0)drop-shadow(#FFFFFF -1px 0 0) drop-shadow(#FFFFFF 0 -1px 0);} |
| #lrc::before {position: absolute;content: attr(data-lrc);width: 95%; height: 95%;color: transparent;overflow: hidden;white-space: pre;background: var(--bg);clip-path: inset(0 100% 0 0);-webkit-background-clip: text;animation: var(--motion) var(--tt) linear forwards;animation-play-state: var(--state);} |
| @keyframes cover1{ to { clip-path: inset(0 0 0 0); } }@keyframes cover2 { to { clip-path: inset(0 0 0 0); } } |
| </style> |
| <script > |
| (function() { |
| /*原始lrc歌词*/ |
| let lrcStr = `[00:00.000] 作词 : 乔羽 作曲:刘炽 |
| |
| [00:05.000] 音画制作:肖燕 |
| |
| [00:12.010]让我们荡起双桨, |
| |
| [00:16.550]小船儿推开波浪, |
| |
| [00:20.910]海面倒映着美丽的白塔, |
| |
| [00:25.390]四周环绕着绿树红墙。 |
| |
| [00:33.190]小船儿轻轻, |
| |
| [00:36.540]飘荡在水中, |
| |
| [00:41.230]迎面吹来凉爽的风。 |
| |
| [00:54.500]红领巾迎着太阳, |
| |
| [00:58.800]阳光洒在海面上, |
| |
| [01:03.760]水中鱼儿望着我们, |
| |
| [01:08.360]悄悄地听我们愉快歌唱。 |
| |
| [01:14.280]小船儿轻轻,飘荡在水中, |
| |
| [01:21.430]迎面吹来了凉爽的风。 |
| |
| [01:31.430] |
| |
| [01:34.430]做完了一天的功课,我们来尽情欢乐。 |
| |
| [01:44.430]我问你亲爱的伙伴,谁给我们安排下幸福的生活? |
| |
| [01:55.430]小船儿轻轻,飘荡在水中, |
| |
| [02:03.430]迎面吹来了凉爽的风。 |
| |
| |
| |
| `; |
| /*变量 :mKey - 当前歌词索引;mFlag :调用关键帧动画索引;averAdd :平均值补偿*/ |
| let mKey = 0, mFlag = true, averAdd = 0.3; |
| /*函数 :获取每句歌词用时,歌词用时若超过平均值则取平均值,最后一句歌词则取平均值*/ |
| 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)) + averAdd; |
| 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 = () => aud.paused ? (lrc.style.setProperty('--state','paused'),mdiv.style.animationPlayState = 'paused') : (lrc.style.setProperty('--state','running'),mdiv.style.animationPlayState = '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> |
| |
| </td></tr></table></td></tr></table> |