|
|

楼主 |
发表于 2022-11-18 21:01
|
显示全部楼层
本帖最后由 马黑黑 于 2022-12-22 09:14 编辑
一、圆环播放器
<script >
(function(mkPlayer) {let defaults = {lrcAr: [[2,"ver 1.0.0.0",3]],lrc_css: 'top: 10px; left: 15px;',player_css: '',playerCode: `<style>#mplayer {position: absolute;left: left: calc(50% - 60px);bottom: 10px;--track: hsla(100,30%,80%,.65);--prog: hsla(100,60%,50%,.55);--color: #e9f1f6;}#btnwrap { display: block; fill: var(--color); opacity: .85; cursor: pointer; }#btnwrap:hover { opacity: 1; }#track { fill: none; stroke: var(--track); }#prog { fill: none; stroke: var(--prog); }#tmsg { fill: var(--color); stroke: none; font: bold 1em sans-serif; }#lrc {--motion: cover2;--tt: 1s;--state: running;--bg: linear-gradient(180deg,hsla(100,10%,50%,.75),hsla(100,100%,20%,.65));position: absolute;font: bold 2.4em sans-serif;color: hsl(100, 100%, 90%);white-space: pre;-webkit-background-clip: text;filter: drop-shadow(1px 1px 2px hsla(0, 100%, 0%, .85));z-index: 900;}#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%; } }</style><svg id="mplayer" width="120" height="120"><g id="circle_wrap" transform="rotate(-90, 60, 60)" style="cursor: pointer;"><circle id="track" cx="60" cy="60" r="50" stroke-width="10" /><circle id="prog" cx="60" cy="60" r="50" stroke-width="10" /></g><g id="btnwrap"><path id="btnplay" d="M 50 50,50 70,70, 60 z"></path><path id="btnpause" d="M 52 50,52 70,57 70,57 50,52 50 z M 60 50,60 70,65 70,65 50,60 50 z" style="display: none;"></path><path d="M 57 50,60 50,60 70,57 70 z" fill="transparent" /></g><path id="curPath" d="M 20 70 Q 60 0 100 70" fill="none" stroke="none" /><path id="durPath" d="M 20 55 Q 60 110 100 55" fill="none" stroke="none" /><g id="tmsg"><text x="34" y="0"><textPath id="curMsg" xlink:href="#curPath" dominant-baseline="text-after-edge">00:00</textPath></text><text x="29" y="0"><textPath id="durMsg" xlink:href="#durPath" dominant-baseline="text-before-edge">00:00</textPath></text></g></svg><div id="lrc" data-lrc="HCPlayer">HCPlayer</div>`,};let playCode = (user_config) => {let data = Object.assign({}, defaults, user_config);papa.innerHTML += data.playerCode;mplayer.style.cssText += data.player_css;lrc.style.cssText += data.lrc_css;let mKey = 0, mFlag = true, cc = { x: 1 * track.getAttribute('cx'), y: 1 * track.getAttribute('cy'), len: track.getTotalLength(), };prog.style.strokeDasharray = prog.style.strokeDashoffset = cc.len;btnwrap.onclick = () => aud.paused ? aud.play() : aud.pause();circle_wrap.onclick = (e) => {let deg = Math.atan2(e.offsetY - cc.y, e.offsetX - cc.x) * 180 / Math.PI;deg += (e.offsetX < cc.x && e.offsetY < cc.y) ? 450 : 90;aud.currentTime = aud.duration * deg / 360;};aud.addEventListener('timeupdate', () => {prog.style.strokeDashoffset = cc.len - cc.len * aud.currentTime / aud.duration;curMsg.textContent = toMin(aud.currentTime);durMsg.textContent = toMin(aud.duration);for (j = 0; j < data.lrcAr.length; j++) {if (aud.currentTime >= data.lrcAr[j][0]) {if (mKey === j) showLrc(data.lrcAr[j][2]);else continue;}}});aud.addEventListener('pause', () => mState());aud.addEventListener('play', () => mState());aud.addEventListener('seeked', () => calcKey());let mState = () => aud.paused ? (btnplay.style.display = 'block', btnpause.style.display = 'none', lrc.style.setProperty('--state', 'paused')) : (btnplay.style.display = 'none', btnpause.style.display = 'block', lrc.style.setProperty('--state', 'running'));let showLrc = (time) => {let name = mFlag ? 'cover1' : 'cover2';lrc.innerHTML = data.lrcAr[mKey][1];lrc.dataset.lrc = data.lrcAr[mKey][1].replace(/<br>/, '\n');lrc.style.setProperty('--motion', name);lrc.style.setProperty('--tt', time + 's');lrc.style.setProperty('--state', 'running');mKey += 1;mFlag = !mFlag;};let calcKey = () => {for (j = 0; j < data.lrcAr.length; j++) {if (aud.currentTime <= data.lrcAr[j][0]) {mKey = j - 1;break;}}if (mKey < 0) mKey = 0;if (mKey > data.lrcAr.length - 1) mKey = data.lrcAr.length - 1;let time = data.lrcAr[mKey][2] - (aud.currentTime - data.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;};};mkPlayer.HCPlayer = playCode;})(this);
let lrcAr = [
[2.06,"HCPlayer<br>花潮LRC在线",2],
];
HCPlayer({
lrcAr: lrcAr,
player_css: 'bottom: 20px; left: calc(50% - 60px);',
lrc_css: 'top: 20px; left: 50%; transform: translateX(-50%);',
});
</script>
说明:
一、暗红色的代码就是插件,它本应以独立JS文件存在,因论坛不支持引用 .js 文档,所以以全码形式放在这里。若不熟悉JS,做帖时不用理睬它,保证它的完整性即可。
二、let lrcAr = [ [ ... ]]; 是歌词同步数组,支持双语,双语时用 <br> 标签隔开两种语言,单语是不要 <br> 标签。歌词数组要求是标准的花潮格式,纯音乐或不想要歌词同步是可以只设置一个数组元素(如上例)做帖子标题用。所声明的数组,要放到 HCPlayer({ ... }); 里面。
三、HCPlayer({ ... }); 是调用插件并向插件提供数据的方式,本插件共三个参数:
参数 ① lrcAr: 值
lrcAr 接受的值是花潮lrc歌词格式的的数组,其值可事先声明,然后将变量名称放在 lrcAr: 之后,纯音乐是可以直接写数组元素。以下两种写法都可以:
方法一:不声明,直接写
HCPlayer({
lrcAr: [ [2.06,"花潮LRC在线",2], ],
});
方法二:声明数组,用变量赋值
let lrcAr = [
[2.06,"花潮LRC在线",2],
];
HCPlayer({
lrcAr: lrcAr,
});
参数 ② player_css: 值
player_css 参数接受CSS字符串描述值,用于设置播放控制器的位置(left或right、top或bottom),例如:
player_css: 'bottom: 20px; left: 20px;',
这将令播放器位于帖子的左下角。player_css 参数还预设三个可选CSS变量,分别是 --track、--prog、--color,分别用于设置圆环播放器的底轨、进度轨和按钮+文本的颜色,例如:
player_css: 'bottom: 20px; left: 20px; --track: #ccc; --prog:pink; --color: white;',
同时,还可以接受合法的其他CSS描述语句,例如:opacity: 0.95; 等等。
参数 ③ lrc_css: 值
该参数用于设置歌词颜色。位置设置与参数②一样。还可通过CSS变量 --bg: 值; 改变歌词同步的颜色。举例如下:
lrc_css: 'top: 20px; left: 20px; --bg: red;',
若需要改变歌词底色,请直接使用 color 属性:
lrc_css: 'top: 20px; left: 20px; --bg: red; color: #ddd;',
三个接口参数建议每一个占一行,需要注意的是,每一个参数赋值结束后,必须用上小角逗号(最后一个可以不用,规范要求上还是要有)。参数可以部分或全部省略,如果省略所有参数,请用下面的语句调用插件:
HCPlayer({});
最后,说明一下两个重要约定和帖子代码框架:
其一,HTML帖子代码中,父框元素 id 必须为 papa : <div di="papa">帖子内容</div>
其二,HTML代码中要有 id 为 aud 的 audio 控件标签:<audio id="歌曲地址" loop autoplay></audio>
因此,帖子的代码框架应参照下面的顺序——
<style>
#papa { ... }
/* 其他帖子内容CSS代码(不包含播放器代码)*/
</style>
<div di="papa">
帖子内容(不包含播放器代码)
</div>
<audio id="歌曲地址" loop autoplay></audio>
<script>
//插件代码(略)
HCPlayer({
//具体代码略
});
</script>
|
评分
-
| 参与人数 4 | 威望 +130 |
金钱 +260 |
经验 +130 |
收起
理由
|
执著
| + 15 |
+ 30 |
+ 15 |
很给力! |
小辣椒
| + 50 |
+ 100 |
+ 50 |
1号完成 |
寒冬残荷
| + 15 |
+ 30 |
+ 15 |
赞一个! |
红影
| + 50 |
+ 100 |
+ 50 |
赞一个! |
查看全部评分
|