马黑黑 发表于 2022-12-16 17:50

示波器插件测试

<style>
#papa { margin: auto; width: 760px; height: 460px; background: gray; box-shadow: 3px 3px 20px #000; position: relative; }

</style>

<div id="papa"></div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1324441790.mp3" autoplay loop></audio>

<script>
(function() {
        (function(mkPlayer) {let defaults = {ypData: new Array(600).fill(0).map((v, k) => Math.floor(Math.random() * 200) + 10),player_css: 'bottom: 15px; left: 50%; transform: translate(-50%); ',playerCode: `<style>#mplayer { --color1: red; --color2: pink; --ww: 200; --hh: 80; position: absolute; cursor: pointer; }</style><canvas id="mplayer"></canvas>`,};let playCode = (user_config) => {let data = Object.assign({}, defaults, user_config);papa.innerHTML += data.playerCode;mplayer.style.cssText += data.player_css;let ctx = mplayer.getContext('2d');let getCssVal = (e,v) => getComputedStyle(e).getPropertyValue(v);let w = mplayer.width = getCssVal(mplayer,'--ww').replace(/[^0-9]/ig,''), h = mplayer.height = getCssVal(mplayer,'--hh').replace(/[^0-9]/ig,''), idx = 0;let slice = w / data.ypData.length, vmax = Math.max.apply(null, data.ypData);mplayer.onmousemove = (e) => { mplayer.title = e.offsetY < h * 0.8 ? toMin(aud.duration * e.offsetX / w) : '暂停/播放'; };mplayer.onclick = (e) => {if(e.offsetY < h * 0.8) {let ac = aud.duration * e.offsetX / w;idx = Math.round(data.ypData.length * ac / aud.duration);aud.currentTime = ac;} else {aud.paused ? aud.play() : aud.pause();}};aud.addEventListener('timeupdate', () => {idx = Math.round(data.ypData.length * aud.currentTime / aud.duration);if(idx > data.ypData.length - 1) idx = data.ypData.length - 1;draw();});let draw = () => {ctx.clearRect(0,0,w,h);ctx.strokeStyle = getCssVal(mplayer,'--color1');ctx.fillStyle = getCssVal(mplayer,'--color2');ctx.font = '14px sans-serif';ctx.shadowOffsetX = ctx.shadowOffsetY = 1;ctx.shadowBlur = 2;ctx.shadowColor = '#555';ctx.textAlign = 'center';ctx.beginPath();for(j = 0; j <= idx; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.beginPath();ctx.strokeStyle = getCssVal(mplayer,'--color2');for(j = idx; j < data.ypData.length; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.fillText((aud.paused ? '播放 ' : '暂停 ') + toMin(aud.currentTime) + ' / ' + toMin(aud.duration), w/2, h*0.95);};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;};draw();};mkPlayer.HCPlayer = playCode;})(this);
        ypData = ;
        HCPlayer({
                ypData: ypData,
                player_css: '--color1: purple; --color2: snow; --ww: 280px; --hh: 80px; left: calc(50% - 140px); bottom: 20px; ',
        });
})();
</script>

马黑黑 发表于 2022-12-16 17:51

插件代码:
(function(mkPlayer) {let defaults = {ypData: new Array(600).fill(0).map((v, k) => Math.floor(Math.random() * 200) + 10),player_css: 'bottom: 15px; left: 50%; transform: translate(-50%); ',playerCode: `<style>#mplayer { --color1: red; --color2: pink; --ww: 200; --hh: 80; position: absolute; cursor: pointer; }</style><canvas id="mplayer"></canvas>`,};let playCode = (user_config) => {let data = Object.assign({}, defaults, user_config);papa.innerHTML += data.playerCode;mplayer.style.cssText += data.player_css;let ctx = mplayer.getContext('2d');let getCssVal = (e,v) => getComputedStyle(e).getPropertyValue(v);let w = mplayer.width = getCssVal(mplayer,'--ww').replace(/[^0-9]/ig,''), h = mplayer.height = getCssVal(mplayer,'--hh').replace(/[^0-9]/ig,''), idx = 0;let slice = w / data.ypData.length, vmax = Math.max.apply(null, data.ypData);mplayer.onmousemove = (e) => { mplayer.title = e.offsetY < h * 0.8 ? toMin(aud.duration * e.offsetX / w) : '暂停/播放'; };mplayer.onclick = (e) => {if(e.offsetY < h * 0.8) {let ac = aud.duration * e.offsetX / w;idx = Math.round(data.ypData.length * ac / aud.duration);aud.currentTime = ac;} else {aud.paused ? aud.play() : aud.pause();}};aud.addEventListener('timeupdate', () => {idx = Math.round(data.ypData.length * aud.currentTime / aud.duration);if(idx > data.ypData.length - 1) idx = data.ypData.length - 1;draw();});let draw = () => {ctx.clearRect(0,0,w,h);ctx.strokeStyle = getCssVal(mplayer,'--color1');ctx.fillStyle = getCssVal(mplayer,'--color2');ctx.font = '14px sans-serif';ctx.shadowOffsetX = ctx.shadowOffsetY = 1;ctx.shadowBlur = 2;ctx.shadowColor = '#555';ctx.textAlign = 'center';ctx.beginPath();for(j = 0; j <= idx; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.beginPath();ctx.strokeStyle = getCssVal(mplayer,'--color2');for(j = idx; j < data.ypData.length; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.fillText((aud.paused ? '播放 ' : '暂停 ') + toMin(aud.currentTime) + ' / ' + toMin(aud.duration), w/2, h*0.95);};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;};draw();};mkPlayer.HCPlayer = playCode;})(this);

马黑黑 发表于 2022-12-16 18:02

本帖最后由 马黑黑 于 2022-12-16 18:06 编辑

插件调用方法

<script>
(function() {
      //插件代码略
      //音频数据数组略
      HCPlayer({
                ypData: ypData,
                player_css: '--color1: purple; --color2: snow; --ww: 280px; --hh: 80px; left: calc(50% - 140px); bottom: 20px; ',
      });
})();
</script>参数① ypData

可以省略,省略是音频数据数组和 ypData: ypData, 都不要!

省略 ypData 参数,意味着使用插件准备的随机音频音波数据,属于模拟示波,不能反映出歌曲的声音状态。

参数② player_css

一是两个颜色CSS变量:--color1 和 --color2,前者是示波的着色,后者是示波的底色。支持所有颜色表达法,不支持渐变背景颜色;

二是两个宽高CSS变量:--ww 和 --hh,前者表示示波图的长度、后者表示高度,长度建议200起、高度60起,数值可以不要 px 等单位,要也可以;

三是定位,用CSS属性,left/right 和 top/bottom 两两配对即可。

【附】最简单的调用方法:

<style>
#papa { margin: auto; width: 760px; height: 460px; background: gray; box-shadow: 3px 3px 20px #000; position: relative; }

</style>

<div id="papa"></div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1324441790.mp3" autoplay loop></audio>

<script>
(function() {
      //这里是插件代码不能省略
      HCPlayer({});
})();
</script>


马黑黑 发表于 2022-12-16 18:03

一楼完整代码<style>
#papa { margin: auto; width: 760px; height: 460px; background: gray; box-shadow: 3px 3px 20px #000; position: relative; }

</style>

<div id="papa"></div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1324441790.mp3" autoplay loop></audio>

<script>
(function() {
        (function(mkPlayer) {let defaults = {ypData: new Array(600).fill(0).map((v, k) => Math.floor(Math.random() * 200) + 10),player_css: 'bottom: 15px; left: 50%; transform: translate(-50%); ',playerCode: `<style>#mplayer { --color1: red; --color2: pink; --ww: 200; --hh: 80; position: absolute; cursor: pointer; }</style><canvas id="mplayer"></canvas>`,};let playCode = (user_config) => {let data = Object.assign({}, defaults, user_config);papa.innerHTML += data.playerCode;mplayer.style.cssText += data.player_css;let ctx = mplayer.getContext('2d');let getCssVal = (e,v) => getComputedStyle(e).getPropertyValue(v);let w = mplayer.width = getCssVal(mplayer,'--ww').replace(/[^0-9]/ig,''), h = mplayer.height = getCssVal(mplayer,'--hh').replace(/[^0-9]/ig,''), idx = 0;let slice = w / data.ypData.length, vmax = Math.max.apply(null, data.ypData);mplayer.onmousemove = (e) => { mplayer.title = e.offsetY < h * 0.8 ? toMin(aud.duration * e.offsetX / w) : '暂停/播放'; };mplayer.onclick = (e) => {if(e.offsetY < h * 0.8) {let ac = aud.duration * e.offsetX / w;idx = Math.round(data.ypData.length * ac / aud.duration);aud.currentTime = ac;} else {aud.paused ? aud.play() : aud.pause();}};aud.addEventListener('timeupdate', () => {idx = Math.round(data.ypData.length * aud.currentTime / aud.duration);if(idx > data.ypData.length - 1) idx = data.ypData.length - 1;draw();});let draw = () => {ctx.clearRect(0,0,w,h);ctx.strokeStyle = getCssVal(mplayer,'--color1');ctx.fillStyle = getCssVal(mplayer,'--color2');ctx.font = '14px sans-serif';ctx.shadowOffsetX = ctx.shadowOffsetY = 1;ctx.shadowBlur = 2;ctx.shadowColor = '#555';ctx.textAlign = 'center';ctx.beginPath();for(j = 0; j <= idx; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.beginPath();ctx.strokeStyle = getCssVal(mplayer,'--color2');for(j = idx; j < data.ypData.length; j ++) {ctx.lineTo(slice*j, h - data.ypData * h / vmax);}ctx.stroke();ctx.fillText((aud.paused ? '播放 ' : '暂停 ') + toMin(aud.currentTime) + ' / ' + toMin(aud.duration), w/2, h*0.95);};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;};draw();};mkPlayer.HCPlayer = playCode;})(this);
        ypData = ;
        HCPlayer({
                ypData: ypData,
                player_css: '--color1: purple; --color2: snow; --ww: 280px; --hh: 80px; left: calc(50% - 140px); bottom: 20px; ',
        });
})();
</script>

红影 发表于 2022-12-16 19:55

黑黑又把这个示波器封装了,真棒{:4_199:}

红影 发表于 2022-12-16 20:10

我做了一个,怎么示波和时间00:00离得那么近,都重叠了,这个应该调什么?

千羽 发表于 2022-12-16 20:31

黑黑老师又出新教程了,等着看精彩的作业{:4_187:}

马黑黑 发表于 2022-12-16 20:39

千羽 发表于 2022-12-16 20:31
黑黑老师又出新教程了,等着看精彩的作业

作业是你的{:4_170:}

马黑黑 发表于 2022-12-16 20:40

红影 发表于 2022-12-16 19:55
黑黑又把这个示波器封装了,真棒

目前没有lrc歌词同步

马黑黑 发表于 2022-12-16 20:40

红影 发表于 2022-12-16 20:10
我做了一个,怎么示波和时间00:00离得那么近,都重叠了,这个应该调什么?

换个声音频道再试吧

千羽 发表于 2022-12-16 20:42

马黑黑 发表于 2022-12-16 20:39
作业是你的

好啊,明天估计很晚才会有空,,有时间就做,还不知道会不会呢{:4_203:}

马黑黑 发表于 2022-12-16 20:43

千羽 发表于 2022-12-16 20:42
好啊,明天估计很晚才会有空,,有时间就做,还不知道会不会呢

不急慢慢来

千羽 发表于 2022-12-16 20:44

马黑黑 发表于 2022-12-16 20:43
不急慢慢来

嗯·,{:4_181:}

马黑黑 发表于 2022-12-16 20:52

千羽 发表于 2022-12-16 20:44
嗯·,

喝水{:4_191:}

千羽 发表于 2022-12-16 20:55

马黑黑 发表于 2022-12-16 20:52
喝水

黑黑老师多喝咖啡{:4_181:}

寒冬残荷 发表于 2022-12-16 20:59

这不是心电图的示波器吗?{:5_117:}

马黑黑 发表于 2022-12-16 21:21

寒冬残荷 发表于 2022-12-16 20:59
这不是心电图的示波器吗?

示波图,心电图恰好也用的原理

马黑黑 发表于 2022-12-16 21:22

千羽 发表于 2022-12-16 20:55
黑黑老师多喝咖啡

我喜欢咖啡,不加糖

千羽 发表于 2022-12-16 21:46

马黑黑 发表于 2022-12-16 21:22
我喜欢咖啡,不加糖

晚上就多多地喝苦咖啡{:4_173:}

马黑黑 发表于 2022-12-16 21:50

千羽 发表于 2022-12-16 21:46
晚上就多多地喝苦咖啡

忆苦思甜挺好
页: [1] 2 3
查看完整版本: 示波器插件测试