马黑黑 发表于 2024-1-26 13:18

家家 - 尘埃

本帖最后由 马黑黑 于 2024-1-26 14:05 编辑 <br /><br /><style>
    #papa { margin: -70px 0 0 calc(50% - 681px); width: 1200px; height: 674px; position: relative; background: lightblue url('https://638183.freep.cn/638183/t24/jpg/ifai.jpg') no-repeat center/cover; box-shadow: 4px 4px 8px rgba(0,0,0,.6); overflow: hidden; display: grid; place-items: center; --state: paused; }
    #mplayer { position: absolute; bottom: 10px; text-align: center; color: white; }
    #mplayer p { margin: 0; padding: 0; cursor: pointer; }
    #mprog { width: 240px; accent-color: darkgreen; outline: none; cursor: pointer; }
    #btnplay { width: 80px; animation: rotating 6s infinite linear var(--state); }
    #lrc { --motion: cover2; --tt: 1s; --bg: linear-gradient(180deg,hsla(100,10%,50%,.75),hsla(100,100%,20%,.65)); position: absolute; top: 15px; 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)); pointer-events: none; z-index: 900; }
    #lrc::before { position: absolute; content: attr(data-lrc); width: 0%; height: 100%; color: transparent; overflow: hidden; white-space: pre; background: var(--bg); filter: inherit; background-clip: text; -webkit-background-clip: text; animation: var(--motion) var(--tt) linear forwards var(--state); }
    #vid { position: absolute; top: -70px; width: 100%; height: calc(100% - 70px); object-fit: cover; pointer-events: none; mix-blend-mode: screen; }
    @keyframes cover1 { from { width: 0%; }to { width: 100%; } }
    @keyframes cover2 { from { width: 0%; }to { width: 100%; } }
    @keyframes rotating { to { transform: rotate(360deg); } }
</style>

<div id="papa">
    <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2005492357" autoplay loop></audio>
    <video id="vid" src="https://img.tukuppt.com/video_show/2629112/00/01/51/5b448e6c1c0ca.mp4" loop muted></video>
    <div id="mplayer">
      <p><img id="btnplay" src="https://638183.freep.cn/638183/small/002_133507167677724892.png" title="播放/暂停" alt="" /></p>
      <output id="mdu">0:00</output>
      <input id="mprog" type="range" min="0" step="1" max="100" value="0" title="调节进度" />
      <output id="mcur">0:00</output>
    </div>
    <div id="lrc" data-lrc="HuaChao LRC Player">HuaChao LRC Player</div>
</div>

<script>
    var geci = [ , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ];
    var sf = document.createElement('script');
    sf.src = 'https://638183.freep.cn/638183/web/js/lrcku.js';
    sf.charset = 'utf-8';
    document.querySelector('body').appendChild(sf);
    sf.onload = () => {
      var mseek = false;
      aud.addEventListener('pause', () => mState());
      aud.addEventListener('playing', () => mState());
        aud.addEventListener('seeked', () => calcKey());
      aud.addEventListener('timeupdate', () => {
            if(!mseek) mprog.value = aud.currentTime / aud.duration * 100;
            mcur.value = toMin(aud.currentTime);
            mdu.value = toMin(aud.duration);
            for (let j = 0; j < geci.length; j++) {
                if (aud.currentTime >= geci) {
                  if (mKey === j) showLrc(geci);
                  else continue;
                }
            }
      });
      mprog.onchange = () => aud.currentTime = mprog.value * aud.duration / 100;
      mprog.onmousedown = () => mseek = true;
      mprog.onmouseup = () => mseek = false;
      mprog.onmousemove = () => {
            if(mseek) mcur.value = toMin(mprog.value * aud.duration / 100);
      };
      btnplay.onclick = () => aud.paused ? aud.play() : aud.pause()
      var mState = () => aud.paused ? (stateSetting(,'--state','paused'), vid.pause()) : (stateSetting(,'--state','running'), vid.play());
    };
</script>

马黑黑 发表于 2024-1-26 13:22

本帖最后由 马黑黑 于 2024-1-26 14:06 编辑

帖子代码<style>
    #papa { margin: 0 0 0 calc(50% - 681px); width: 1200px; height: 674px; position: relative; background: lightblue url('https://638183.freep.cn/638183/t24/jpg/ifai.jpg') no-repeat center/cover; box-shadow: 4px 4px 8px rgba(0,0,0,.6); overflow: hidden; display: grid; place-items: center; --state: paused; }
    #mplayer { position: absolute; bottom: 10px; text-align: center; color: white; }
    #mplayer p { margin: 0; padding: 0; cursor: pointer; }
    #mprog { width: 240px; accent-color: darkgreen; outline: none; cursor: pointer; }
    #btnplay { width: 80px; animation: rotating 6s infinite linear var(--state); }
    #lrc { --motion: cover2; --tt: 1s; --bg: linear-gradient(180deg,hsla(100,10%,50%,.75),hsla(100,100%,20%,.65)); position: absolute; top: 15px; 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)); pointer-events: none; z-index: 900; }
    #lrc::before { position: absolute; content: attr(data-lrc); width: 0%; height: 100%; color: transparent; overflow: hidden; white-space: pre; background: var(--bg); filter: inherit; background-clip: text; -webkit-background-clip: text; animation: var(--motion) var(--tt) linear forwards var(--state); }
    #vid { position: absolute; top: -70px; width: 100%; height: calc(100% - 70px); object-fit: cover; pointer-events: none; mix-blend-mode: screen; }
    @keyframes cover1 { from { width: 0%; }to { width: 100%; } }
    @keyframes cover2 { from { width: 0%; }to { width: 100%; } }
    @keyframes rotating { to { transform: rotate(360deg); } }
</style>

<div id="papa">
    <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2005492357" autoplay loop></audio>
    <video id="vid" src="https://img.tukuppt.com/video_show/2629112/00/01/51/5b448e6c1c0ca.mp4" loop muted></video>
    <div id="mplayer">
      <p><img id="btnplay" src="https://638183.freep.cn/638183/small/002_133507167677724892.png" title="播放/暂停" alt="" /></p>
      <output id="mdu">0:00</output>
      <input id="mprog" type="range" min="0" step="1" max="100" value="0" title="调节进度" />
      <output id="mcur">0:00</output>
    </div>
    <div id="lrc" data-lrc="HuaChao LRC Player">HuaChao LRC Player</div>
</div>

<script>
    var geci = [ , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ];
    var sf = document.createElement('script');
    sf.src = 'https://638183.freep.cn/638183/web/js/lrcku.js';
    sf.charset = 'utf-8';
    document.querySelector('body').appendChild(sf);
    sf.onload = () => {
      var mseek = false;
      aud.addEventListener('pause', () => mState());
      aud.addEventListener('playing', () => mState());
        aud.addEventListener('seeked', () => calcKey());
      aud.addEventListener('timeupdate', () => {
            if(!mseek) mprog.value = aud.currentTime / aud.duration * 100;
            mcur.value = toMin(aud.currentTime);
            mdu.value = toMin(aud.duration);
            for (let j = 0; j < geci.length; j++) {
                if (aud.currentTime >= geci) {
                  if (mKey === j) showLrc(geci);
                  else continue;
                }
            }
      });
      mprog.onchange = () => aud.currentTime = mprog.value * aud.duration / 100;
      mprog.onmousedown = () => mseek = true;
      mprog.onmouseup = () => mseek = false;
      mprog.onmousemove = () => {
            if(mseek) mcur.value = toMin(mprog.value * aud.duration / 100);
      };
      btnplay.onclick = () => aud.paused ? aud.play() : aud.pause()
      var mState = () => aud.paused ? (stateSetting(,'--state','paused'), vid.pause()) : (stateSetting(,'--state','running'), vid.play());
    };
</script>

马黑黑 发表于 2024-1-26 13:30

本帖最后由 马黑黑 于 2024-1-26 14:07 编辑

帖子引用一个外部JS lrcku.js,它的作用是提供lrc歌词显示的解决方案,因为内容偏多,所以剥离出来。该JS文件:

lrcku.js :

(一)公用变量 mKey :用于处理歌词数组索引,供 audio 控件的 timeupdate 事件使用;
(二)相关函数:

① stateSetting(元素数组, 状态名称, 状态值) :用于设置 CSS变量,以控制关键帧动画。参数一是元素id名称数组,如:;参数二是CSS变量名称,如:'--state';状态值只有两个,要么是 'paused',要么是'running';

② showLrc(时间) :显示歌词,供 audio 控件的 timeupdate 事件使用;

③ toMin(值) :格式化时间输出,以 分:秒 的形式换算 audio 空间的时间信息。供 audio 控件的 timeupdate 事件使用;

④ calcKey() :处理当前歌词索引,供 audio 的 seeked 监听事件调用。


帖子中播放器的 timeupdate 监听事件要使用公用变量 mKey 作为显示歌词的依据;mState 函数可自定义,对CSS关键帧动画的控制使用 stateSetting 函数可以简化帖子代码,其它的自己加上(比如例中的视频控制);showLrc 和 toMin 函数也用在 timeupdate 事件监听代码块中,可按帖子代码的使用方式应用到自己的帖子里。

马黑黑 发表于 2024-1-26 13:34

本帖,主要用意两个:

一是使用HTML range 滑杆做可控的进度条,二是将lrc歌词显示的实现机制的JS抽象部分剥离出来(CSS和HTML需要在帖子中安排,audio 控件的几个监听事件也在帖子中完成)。

马黑黑 发表于 2024-1-26 13:44

关于 range 滑杆:

CSS 简单定义了外观颜色;

JS 变量 mseek 用于处理滑杆滑块拖动时与音频播放的协调问题。

滑杆的JS相关事件:

鼠标按下:mseek 变量为真,此时拖动滑块audio控件暂时不驱动滑杆运行;
鼠标移动:指按下左键移动(mseek = true)时,显示当前变更的进度应播放的时间;
鼠标松开:指松开左键时,mseek = false,随后鼠标的移动不会发生作用;
onchange :指更改进度动作完成时,audio应从改变的值播放音乐(音乐处于暂停状态时需点击一下播放按钮)。

马黑黑 发表于 2024-1-26 14:13

关于 audio 的几个监听事件:

帖子需要显示歌词的,本例的所有监听事件都不能少。

如果是纯音乐帖,则:

不要 seeked 监听事件;

将 timeupdate 监听事件中的以下代码删掉:

            for (let j = 0; j < geci.length; j++) {
                if (aud.currentTime >= geci) {
                  if (mKey === j) showLrc(geci);
                  else continue;
                }
            }

同时,歌词数组变量 geci 删掉、CSS和HTML的lrc相关语句全部删掉。

红影 发表于 2024-1-26 14:42

这个好,就可以设置和其他JS不冲突的情况下加入歌词同步和歌曲进度了吧{:4_199:}

红影 发表于 2024-1-26 14:45

马黑黑 发表于 2024-1-26 13:30
帖子引用一个外部JS lrcku.js,它的作用是提供lrc歌词显示的解决方案,因为内容偏多,所以剥离出来。该JS文 ...

stateSetting(元素数组, 状态名称, 状态值) :用于设置 CSS变量,以控制关键帧动画。
这个可以让多个动态都被控制了吧{:4_187:}

红影 发表于 2024-1-26 14:46

这能不能把当前时间放前面,总时间放后面。比较习惯的样子{:4_173:}

红影 发表于 2024-1-26 14:48

马黑黑 发表于 2024-1-26 13:34
本帖,主要用意两个:

一是使用HTML range 滑杆做可控的进度条,二是将lrc歌词显示的实现机制的JS抽象部 ...

这样自己调整的可能性更大点{:4_187:}

红影 发表于 2024-1-26 14:51

马黑黑 发表于 2024-1-26 13:44
关于 range 滑杆:

CSS 简单定义了外观颜色;


这个是就上个帖子里黑黑说的火柴棒呢,被黑黑实际应用在帖子中了{:4_199:}

红影 发表于 2024-1-26 14:57

马黑黑 发表于 2024-1-26 14:13
关于 audio 的几个监听事件:

帖子需要显示歌词的,本例的所有监听事件都不能少。


不要歌词同步也能让火柴棒跟着进度,厉害了。
还有个简单办法,把歌词内容设为空也可以吧?

红影 发表于 2024-1-26 14:58

黑黑总带来新的东西,每次进来都先忙着看代码,都忘了欣赏帖子。
这个帖子背景和歌曲特别相配,很赞。歌曲也特别好听呢。很赞{:4_199:}

樵歌 发表于 2024-1-26 15:27

风云变幻,要变天了哇,有点恐怕。{:4_189:}

马黑黑 发表于 2024-1-26 19:13

樵歌 发表于 2024-1-26 15:27
风云变幻,要变天了哇,有点恐怕。

不会吧

马黑黑 发表于 2024-1-26 19:13

红影 发表于 2024-1-26 14:58
黑黑总带来新的东西,每次进来都先忙着看代码,都忘了欣赏帖子。
这个帖子背景和歌曲特别相配,很赞。歌曲 ...

感谢支持

马黑黑 发表于 2024-1-26 19:17

红影 发表于 2024-1-26 14:45
stateSetting(元素数组, 状态名称, 状态值) :用于设置 CSS变量,以控制关键帧动画。
这个可以让多个动 ...

会的话可以的,其实也简单:能从父元素继承的 --state 变量就不用管,不能继承的(比如lrc伪元素不能继承爷爷辈的--state变量)就将 id 或业已声明的其他变量标识添加到mState函数的数组中:

stateSetting(mydiv], ....

马黑黑 发表于 2024-1-26 19:23

红影 发表于 2024-1-26 14:57
不要歌词同步也能让火柴棒跟着进度,厉害了。
还有个简单办法,把歌词内容设为空也可以吧?

没有歌词一切才简单的。等下我出一个系列教程之一,保公级别的,你就可以感受到我说的了

马黑黑 发表于 2024-1-26 19:23

红影 发表于 2024-1-26 14:51
这个是就上个帖子里黑黑说的火柴棒呢,被黑黑实际应用在帖子中了

这个应用不值一提

马黑黑 发表于 2024-1-26 19:24

红影 发表于 2024-1-26 14:48
这样自己调整的可能性更大点

应该是
页: [1] 2 3 4 5 6 7
查看完整版本: 家家 - 尘埃