【水芙蓉播放器】风雨天涯
<style>@import url("https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap");#papa{position: relative;margin: 30px 0px;display: grid;place-items: center;width: 1300px;height: 720px;left: calc(50% - 81px);transform: translateX(-50%);box-shadow: 3px 3px 6px gray;overflow: hidden;z-index: 10000;background: #0000 ;font-family: "Ma Shan Zheng","华文行楷","SimHei", "Arial", "sans-serif";
}
#gradient {position: absolute;margin: 0px 0px;
width: 100%;z-index: 1;
height: 100%;transform: scale(1.1);
background:url(https://img-baofun.zhhainiao.com/fs/scene/preview_img_raw/48fc8dfae65ca5e332393f69cfd02d3f.jpg) no-repeat 0 0px/cover,linear-gradient(122deg,#880000, #aa6600, #3d9c31, #000090);
filter: url(#water);
background-blend-mode:overlay, difference, normal, lighten ;
}
#dt {position: absolute;margin: 0px 0px;
width: 100%;mix-blend-mode:lighten ;z-index: 2;
height: 100%;}
#dt img{
width: 100%;
height: 100%;}
.lyricDisp{transition:.5s all ease;text-align:center;color:#fff000;filter:drop-shadow(#000 1px 0 0)drop-shadow(#000 0 1px 0)drop-shadow(#000 -1px 0 0) drop-shadow(#000 0 -1px0);line-height: 50px;--bg:linear-gradient(90deg, #00aa00, #ff0000, #00ff00, #800000, #ff0000);margin: 0;padding: 0;}
.lyricDisp.highlight{font-size:1.5em;color:#00cc00;--aniName:bgMove1;--durTime:100ms;--aniPlayState:running;}
.lyricDisp.highlight::before{position:absolute;content:attr(data-lrc);width:10%;height:100%;color:transparent;overflow:hidden;white-space:nowrap;animation:var(--aniName) var(--durTime) linear forwards;animation-play-state:var(--aniPlayState);background: var(--bg);-webkit-background-clip: text;text-align:left;}
@keyframes bgMove1{from{width:0%;}to{width:100%;}}@keyframes bgMove0{from{width:0%}to{width:100%;}}
.LRCShow{position:absolute;left:8%;top: 20%;width:53%;height: 30%;font-weight:390;font-size:1.6em;z-index: 9;display: flex;flex-direction: column;justify-content: center;align-items: center;gap: 2px;-webkit-box-reflect: below -15% -webkit-gradient(linear, 0 0, 0 120%, from(transparent), color-stop(.0, transparent), to(rgba(3,3,3,1)));
background: -webkit-linear-gradient(top, rgba(174,188,191,1) 0%,rgba(110,119,116,1) 50%,rgba(10,14,10,1) 51%,rgba(10,8,9,1) 100%);
-webkit-background-clip: text;-webkit-text-fill-color: ;}
#player {position: absolute;top: 76%;right: 43%;width: 140px;
height: 140px;
display: grid;cursor:pointer;
place-items: center;animation: starfish-rotate 3s linear infinite;transform-origin: center;transform-style: preserve-3d;transition: transform 0.3s ease;z-index: 100;}
@keyframes starfish-rotate {to {transform:rotateZ(360deg);}}
#rect {position: absolute;
display: grid;
place-items: center;
width:35%;
height: 35%;
clip-path: polygon(60% 0, 100% 0, 50% 50%, 40% 100%, 0 100%, 50% 50%);
}
#rect:nth-of-type(1) { background:#5500ff;transform: rotate(0deg);
}
#rect:nth-of-type(2) { background:#ff0000;transform: rotate(45deg);
}
#rect:nth-of-type(3) { background:#00aa00;transform: rotate(90deg);
}
#rect:nth-of-type(4) { background:#fff000;transform: rotate(135deg);
}
.stop #player{animation-play-state: paused;}
#fullscreen{border-radius: 4px;position: absolute;
color:#fff;background:#0000;box-shadow:0px 0px 0px 0px #fff;
padding: 4px 8px;z-index: 120;
font-size: 25px;font-weight: 100;
border: none;
cursor: pointer;top: 5px;left: 8%;
}
#mplayer{position:absolute;text-align:center;top:95%;transform:translate(-50%);left:50%;z-index:100;font-size:18px;color:#7CFC00;}
#mplayer::before{position:absolute;content:attr(data-tt);left:0;bottom:23px;width:100%;text-align-last:justify;}
#mprog{width:500px;height:2px;accent-color:darkgreen;outline:none;cursor:pointer;}
#papa p {position: absolute;width: 50px;height: 350px;z-index: 3;left:8%;top: 25%;writing-mode: vertical-rl;text-orientation: upright;font: bold 4.5em/1.5 STLiti;letter-spacing: 30px;white-space: pre;color: #7CFC00; }
</style>
<div id="papa">
<div id="fullscreen">全屏欣赏</div>
<svg width="0" height="0" id="reflect">
<filter id="water">
<feTurbulence type="fractalNoise" baseFrequency=".05 .01" numOctaves="1" result="noise1"></feTurbulence>
<feColorMatrix in="noise1" type="hueRotate" values="0" result="noise2">
<animate attributeName="values" from="0" to="360" dur="1s" repeatCount="indefinite"/>
</feColorMatrix>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="7" in="SourceGraphic" in2="noise2" />
</filter>
</svg>
<div id="gradient"></div>
<div id="dt"> <img src="https://img2.oldkids.cn/upload/2026/04/06/photo_0_20260406153610799.gif"id="IMGb" /></div>
<div id="testImg"><div id="player"title="暂停/播放" >
<spanid="rect"></span>
<spanid="rect"></span>
<spanid="rect"></span>
<spanid="rect"></span>
</div>
</div>
<div id="mplayer" data-tt="00:00 00:00"><input id="mprog" type="range" min="0" max="100" step="any" value="0" title=""/></div>
<div class="LRCShow"></div>
</div>
<script type="text/javascript">
var lrcPlayerM=function(){return this.init.apply(this,arguments)};
lrcPlayerM.prototype={
constructor:lrcPlayerM,
init:function(opts){
this.showLrcObj=document.querySelector('.LRCShow');
this.player=document.getElementById('player');
this.image=document.getElementById('testImg');
this.reflect=document.getElementById('reflect');
this.imageb= document.getElementById("IMGb");
this.gclines=new Array();
this.slines=typeof opts.showLines==='number'?opts.showLines:1;
this.midLineIdx = Math.floor(this.slines / 2);
for(k=0;k<this.slines;k++){
this.gclines=document.createElement('div');
this.gclines.className='lyricDisp';
if(k === this.midLineIdx) this.gclines.classList.add('highlight');
this.showLrcObj.appendChild(this.gclines)
}
this.handleLrc(opts.lrcDoc);
this.genPlayer(opts.audioURL)
},
handleLrc:function(lyricTxt){
this.lrcVec=new Array();
var lyriclist=lyricTxt.split(/\r|\n|\r\n/);
for(n=0;n<lyriclist.length;n++){
chkTime=lyriclist.match(/\[\d{1,2}:\d{2}.\d{1,3}\]|\[\d{1,2}:\d{2}\]/g);
if(chkTime){
tIdx=lyriclist.lastIndexOf(']');
if(tIdx>0)lrcTxt=lyriclist.substr(tIdx+1);
for(m=0;m<chkTime.length;m++){
ta=chkTime.substr(1).replace(']','').split(/:/);
_t=(+ta)*60+(+ta);
if(this.lrcVec.length==0&&_t!=0){this.lrcVec.push()}
this.lrcVec.push()
}
}
}
this.lrcVec.sort(function(a,b){return(a-b)})
},
showLrc:function(durTime){
this.gclines.innerHTML=this.gclines.dataset.lrc=this.lrcVec.length>0?this.lrcVec:"\u3000";
this.gclines.style.setProperty('--aniName','bgMove'+(this.idx%2));
this.gclines.style.setProperty('--durTime',durTime+'ms');
this.gclines.style.setProperty('--aniPlayState','running')
},
genPlayer:function(mUrl){
this.mObj=document.createElement("audio");
this.mObj.loop=false;
this.mObj.muted=false;
this.mObj.src=mUrl;
this.mObj.id = 'bgMusic';
this.mObj.playsinline = true;
this.mObj.setAttribute('webkit-playsinline', 'true');
this.showLrcObj.appendChild(this.mObj);
this.idx=0;
var that=this;
this.mObj.addEventListener('ended',function(){that.idx=0;this.play()});
this.mObj.addEventListener('playing',function(){that.gclines.style.setProperty('--aniPlayState','running')});
this.mObj.addEventListener('pause',function(){that.gclines.style.setProperty('--aniPlayState','paused')});
this.mObj.addEventListener('error',function(){console.log("audio wrong, remove play start event");that.showLrcObj.style.display='none';that.showLrcObj.removeChild(this)});
this.mObj.addEventListener('timeupdate',function(){
if(that.idx>=that.lrcVec.length)return;
if(this.currentTime>that.lrcVec){
if(that.idx<(that.lrcVec.length-1)){
that.showLrc((that.lrcVec-that.lrcVec)*950)
}else{
that.showLrc((this.duration-that.lrcVec)*950)
}
for(let n = 0; n < that.slines; n++){
if(n === that.midLineIdx) continue;
let offset = n - that.midLineIdx;
let lrcIndex = that.idx + offset;
if(lrcIndex < 0 || lrcIndex >= that.lrcVec.length){
that.gclines.innerHTML = "\u3000";
}else{
that.gclines.innerHTML = that.lrcVec || "\u3000";
}
}
that.idx++
}
});
this.player.onclick=function(){
if(that.mObj.paused){
that.mObj.play();
that.image.classList.remove('stop');
that.imageb.play();
that.reflect.unpauseAnimations();
document.getElementById('papa').style.setProperty('--bgd');
}else{
that.mObj.pause();
that.image.classList.add('stop');
that.reflect.pauseAnimations();
that.imageb.stop();
document.getElementById('papa').style.setProperty('--bgd');
}
};
try{this.mObj.play()}catch(err){console.log(err.message)}
},
stopMusic:function(){this.mObj.pause();this.mObj.controls=false;},
setAudioUrl:function(mUrl){this.mObj.src=mUrl},
isMusicEnd:function(){return this.mObj.ended},
reStart:function(){this.idx=0;this.mObj.play()}
}
let lrctxt = `
风雨天涯(女版)
词:歌奴(尹庆全)
曲:歌奴(尹庆全)
LRC编辑:醉美水芙蓉
演唱:江念念
寒雨连绵丝丝凉
风卷落叶绕身旁
遥望远方路漫长
雨泪滑落湿衣裳
星月无光夜凄凉
天光无影心迷茫
恍惚梦中旧模样
思乡滋味在心房
风雨天涯泪涟涟
风啸声声过千山
孤身漂泊天地间
归期遥遥路漫漫
星月无光夜凄凉
天光无影心迷茫
恍惚梦中旧模样
思乡滋味在心房
风雨天涯路漫长
风载乡愁飘四方
天涯万里风雨狂
梦里牵挂从未放
风雨天涯望星光
风拂归程念故乡
心揣着梦不彷徨
风雨天涯向远方
风雨天涯向远方
☆★谢谢欣赏★☆
`;
var opts = {
lrcDoc:lrctxt,
audioURL:"https://mpimg.cn/view.php/a992cbecfb52de744330ce8d5adc52f8.mp3",
showLines:3,
};
var lrcPlayer = new lrcPlayerM(opts);
const fullscreen = document.getElementById('fullscreen');
let fs = true;
fullscreen.onclick = () => {
if (fs) {
fullscreen.innerText = '退出全屏';
papa.requestFullscreen();
} else {
fullscreen.innerText = '全屏欣赏';
document.exitFullscreen();
}
fs = !fs;
};
['contextmenu', 'dragstart','selectstart'].forEach(type =>
document.getElementById('papa').addEventListener(type, e => e.preventDefault()));
player.onanimationiteration = () => player.style.setProperty('filter', `hue-rotate(${0 + Math.random() * 270}deg)`);
const audio = document.getElementById('bgMusic') || lrcPlayer.mObj;
const mplayer = document.getElementById('mplayer');
const mprog = document.getElementById('mprog');
var mseek = false;
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;
}
function findLrcIndexByTime(audioTime, lrcVec) {
for (let i = lrcVec.length - 1; i >= 0; i--) {
if (lrcVec <= audioTime) {
return i;
}
}
return 0;
}
audio.addEventListener('loadedmetadata', () => {
mplayer.dataset.tt = toMin(0) + ' ' + toMin(audio.duration);
});
audio.addEventListener('timeupdate', () => {
if(!audio.duration) return;
if(!mseek) mprog.value = (audio.currentTime / audio.duration) * 100;
mplayer.dataset.tt = toMin(audio.currentTime) + ' ' + toMin(audio.duration);
});
mprog.onmousedown = () => mseek = true;
mprog.onmouseup = () => mseek = false;
mprog.onchange = () => {
if (!audio.duration) return;
const targetTime = (mprog.value / 100) * audio.duration;
audio.currentTime = targetTime;
const targetIdx = findLrcIndexByTime(targetTime, lrcPlayer.lrcVec);
lrcPlayer.idx = targetIdx;
let durTime = 0;
if (targetIdx < lrcPlayer.lrcVec.length - 1) {
durTime = (lrcPlayer.lrcVec - lrcPlayer.lrcVec) * 950;
} else {
durTime = (audio.duration - lrcPlayer.lrcVec) * 950;
}
lrcPlayer.showLrc(durTime);
for (let n = 0; n < lrcPlayer.slines; n++) {
if (n === lrcPlayer.midLineIdx) continue;
let offset = n - lrcPlayer.midLineIdx;
let lrcIndex = targetIdx + offset;
if (lrcIndex < 0 || lrcIndex >= lrcPlayer.lrcVec.length) {
lrcPlayer.gclines.innerHTML = "\u3000";
} else {
lrcPlayer.gclines.innerHTML = lrcPlayer.lrcVec || "\u3000";
}
}
};
mprog.oninput = () => {
if(!audio.duration) return;
let currentTime = (mprog.value / 100) * audio.duration;
mplayer.dataset.tt = toMin(currentTime) + ' ' + toMin(audio.duration);
lrcPlayer.idx = 0;
for(let line of lrcPlayer.gclines){
line.innerHTML = "\u3000";
}
};
</script>
<script>
if ('getContext' in document.createElement('canvas')) {
HTMLImageElement.prototype.play = function() {
if (this.storeCanvas) {
// 洢canvas
this.storeCanvas.parentElement.removeChild(this.storeCanvas);
this.storeCanvas = null;
//
imageb.style.opacity = '';
}
if (this.storeUrl) {
this.src = this.storeUrl;
}
};
HTMLImageElement.prototype.stop = function() {
var canvas = document.createElement('canvas');
//
var width = this.width, height = this.height;
if (width && height) {
// 洢
if (!this.storeUrl) {
this.storeUrl = this.src;
}
// canvasС
canvas.width = width;
canvas.height = height;
//
canvas.getContext('2d').drawImage(this, 0, 0, width, height);
//
try {
this.src = canvas.toDataURL("image/gif");
} catch(e) {
//
this.removeAttribute('src');
// canvas
canvas.style.position = 'absolute';
//
this.parentElement.insertBefore(canvas, this);
//
this.style.opacity = '0';
// 洢canvas
this.storeCanvas = canvas;
}
}
};
}
var imageb= document.getElementById("IMGb");
</script> 撒花花
芙蓉晚上好
{:9_269:} 这款同步歌词还有倒影~~{:4_123:} 好听,嗓音高亢带一点沧桑感
蛐蛐好有画面感,勾勒出一幅天涯风雨的场景 渐变色运用的真好,播放器漂亮,同步歌词制作的精准又好看~~ 芙蓉制作辛苦了
谢谢带来精美的音乐帖
{:5_130:} 绿蔷薇 发表于 2026-4-22 20:57
这款同步歌词还有倒影~~
咦果然,破薇细心{:9_286:} 真好听哦,播放器好看嘀{:9_272:} 绿蔷薇 发表于 2026-4-22 21:01
芙蓉制作辛苦了
谢谢带来精美的音乐帖
谢谢友友支持! 念若莲 发表于 2026-4-23 10:39
真好听哦,播放器好看嘀
谢谢友友支持!