马黑黑 发表于 2023-3-15 07:43

熊猫之歌

本帖最后由 马黑黑 于 2023-3-15 08:08 编辑 <br /><br /><style>
#papa {
        --state: paused;
        margin: -80px 0 0 calc(50% - 593px);
        width: 1024px;
        height: 640px;
        background: lightgreen url('https://638183.freep.cn/638183/t23/webp/panda.webp') center/cover no-repeat;
        box-shadow: 3px 3px 20px #000;
        display: grid;
        place-items: center;
        position: relative;
}
#lrc {
        --motion: cover2;
        --tt: 2s;
        --bg: linear-gradient(180deg, hsla(60, 50%, 50%, .45), hsla(80, 70%, 50%, .65));
        position: absolute;
        top: 20px;
        font: bold 2em sans-serif;
        color: snow;
        white-space: pre;
        -webkit-background-clip: text;
        filter: drop-shadow(1px 1px 2px hsla(0, 0%, 0%, .95));
}
#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);
}
#face {
        position: absolute;
        top: 80px;
        width: 100px;
        height: 100px;
        border: 1px solid #fff;
        border-radius: 100% 100% 80% 80%;
        cursor: pointer;
}
#face > span {
        position: absolute;
        top: 30px;
        width: 10px;
        height: 16px;
        border-radius: 50%;
        background: #000;
}
#face > span:nth-of-type(1) {
        left: 20px;
        animation: mov .5s infinitealternate var(--state);
        --xx: 10px;
}
#face > span:nth-of-type(2) {
        left: 70px;
        animation: mov .5s infinite linear alternate var(--state);
        --xx: -10px;
}
#face > span:nth-of-type(3) {
        height: 8px;
        background: none;
        border: 1px solid #000;
        top: 60px;
        left: 45px;
        transform: scale(.5);
        animation: scale .15s infinite alternate var(--state);
}
@keyframes cover1 { from { width: 0; } to { width: 100%; } }
@keyframes cover2 { from { width: 0; } to { width: 100%; } }
@keyframes mov {to { transform: translate(var(--xx)); } }
@keyframes scale { to {transform: scale(1.5); } }
</style>

<div id="papa">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=498880703.mp3" loop autoplay></audio>
        <div id="lrc" data-lrc="HCPlayer">HCPlayer</div>
        <div id="face">
                <span></span>
                <span></span>
        <span></span>
</div>
</div>

<script>
let averAdd = 0, offset = 0, mKey = 0, mFlag = true;

let lrcTime = (ar) => {let tmpAr = [];for (j = 0; j < ar.length - 1; j++) {if (j !== ar.length - 1) tmpAr = parseFloat((ar - ar).toFixed(1));}let aver = parseInt(tmpAr.reduce((a, b) => a + b) / (tmpAr.length - 1)) + averAdd;tmpAr.push(aver);tmpAr.forEach((item, key) => {ar = item > aver ? aver : item;});return ar;};
let getLrcAr = (text) => {let lrcAr = [];let calcRule = ;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 * calcRule;ar = ;lrcAr.push(ar);}}}}lrcAr.sort((a, b) => a - b);return (lrcTime(lrcAr));}
let showLrc = (time) => {let name = mFlag ? 'cover1' : 'cover2';lrc.innerHTML = lrcAr;lrc.dataset.lrc = lrcAr;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 < lrcAr.length; j++) { if (aud.currentTime <= lrcAr) { mKey = j - 1; break; } } if (mKey < 0) mKey = 0; if (mKey > lrcAr.length - 1) mKey = lrcAr.length - 1; let time = lrcAr - (aud.currentTime - lrcAr); showLrc(time); };
let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');

let lrcAr = getLrcAr('刘禹鑫 & 王梓濠 熊猫之歌\n我有一副可爱身材\n颜色经典只有黑白\n我的胃口一向不坏\n嚼着竹子欢乐开怀\n熊猫之歌\n有时我也想搞搞怪\n拍张照片有点色彩\n我的伙伴无处不在\n好玩的游戏一起来\n熊猫之歌\n我有一副可爱身材\n颜色经典只有黑白\n我的胃口一向不坏\n嚼着竹子欢乐开怀\n有时我也想搞搞怪\n拍张照片有点色彩\n我的伙伴无处不在\n好玩的游戏一起来\n感谢支持');
aud.addEventListener('timeupdate', () => {for (j = 0; j < lrcAr.length; j++) {if (aud.currentTime >= lrcAr) {cKey = j;if (mKey === j) showLrc(lrcAr);else continue;}}});
aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());
aud.addEventListener('seeked', () => calcKey());
face.addEventListener('click', () => aud.paused ? aud.play() : aud.pause());
</script>

马黑黑 发表于 2023-3-15 07:49

本帖最后由 马黑黑 于 2023-3-15 08:08 编辑

帖子代码:
<style>
#papa {
      --state: paused;
      margin: -80px 0 0 calc(50% - 593px);
      width: 1024px;
      height: 640px;
      background: lightgreen url('https://638183.freep.cn/638183/t23/webp/panda.webp') center/cover no-repeat;
      box-shadow: 3px 3px 20px #000;
      display: grid;
      place-items: center;
      position: relative;
}
#lrc {
      --motion: cover2;
      --tt: 2s;
      --bg: linear-gradient(180deg, hsla(60, 50%, 50%, .45), hsla(80, 70%, 50%, .65));
      position: absolute;
      top: 20px;
      font: bold 2em sans-serif;
      color: snow;
      white-space: pre;
      -webkit-background-clip: text;
      filter: drop-shadow(1px 1px 2px hsla(0, 0%, 0%, .95));
}
#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);
}
#face {
      position: absolute;
      top: 80px;
      width: 100px;
      height: 100px;
      border: 1px solid #fff;
      border-radius: 100% 100% 80% 80%;
      cursor: pointer;
}
#face > span {
      position: absolute;
      top: 30px;
      width: 10px;
      height: 16px;
      border-radius: 50%;
      background: #000;
}
#face > span:nth-of-type(1) {
      left: 20px;
      animation: mov .5s infinitealternate var(--state);
      --xx: 10px;
}
#face > span:nth-of-type(2) {
      left: 70px;
      animation: mov .5s infinite linear alternate var(--state);
      --xx: -10px;
}
#face > span:nth-of-type(3) {
      height: 8px;
      background: none;
      border: 1px solid #000;
      top: 60px;
      left: 45px;
      transform: scale(.5);
      animation: scale .15s infinite alternate var(--state);
}
@keyframes cover1 { from { width: 0; } to { width: 100%; } }
@keyframes cover2 { from { width: 0; } to { width: 100%; } }
@keyframes mov {to { transform: translate(var(--xx)); } }
@keyframes scale { to {transform: scale(1.5); } }
</style>

<div id="papa">
      <audio id="aud" src="https://music.163.com/song/media/outer/url?id=498880703.mp3" loop autoplay></audio>
      <div id="lrc" data-lrc="HCPlayer">HCPlayer</div>
      <div id="face">
                <span></span>
                <span></span>
                <span></span>
</div>
</div>

<script>
let averAdd = 0, offset = 0, mKey = 0, mFlag = true;

let lrcTime = (ar) => {let tmpAr = [];for (j = 0; j < ar.length - 1; j++) {if (j !== ar.length - 1) tmpAr = parseFloat((ar - ar).toFixed(1));}let aver = parseInt(tmpAr.reduce((a, b) => a + b) / (tmpAr.length - 1)) + averAdd;tmpAr.push(aver);tmpAr.forEach((item, key) => {ar = item > aver ? aver : item;});return ar;};
let getLrcAr = (text) => {let lrcAr = [];let calcRule = ;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 * calcRule;ar = ;lrcAr.push(ar);}}}}lrcAr.sort((a, b) => a - b);return (lrcTime(lrcAr));}
let showLrc = (time) => {let name = mFlag ? 'cover1' : 'cover2';lrc.innerHTML = lrcAr;lrc.dataset.lrc = lrcAr;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 < lrcAr.length; j++) { if (aud.currentTime <= lrcAr) { mKey = j - 1; break; } } if (mKey < 0) mKey = 0; if (mKey > lrcAr.length - 1) mKey = lrcAr.length - 1; let time = lrcAr - (aud.currentTime - lrcAr); showLrc(time); };
let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');

let lrcAr = getLrcAr('刘禹鑫 & 王梓濠 熊猫之歌\n我有一副可爱身材\n颜色经典只有黑白\n我的胃口一向不坏\n嚼着竹子欢乐开怀\n熊猫之歌\n有时我也想搞搞怪\n拍张照片有点色彩\n我的伙伴无处不在\n好玩的游戏一起来\n熊猫之歌\n我有一副可爱身材\n颜色经典只有黑白\n我的胃口一向不坏\n嚼着竹子欢乐开怀\n有时我也想搞搞怪\n拍张照片有点色彩\n我的伙伴无处不在\n好玩的游戏一起来\n感谢支持');
aud.addEventListener('timeupdate', () => {for (j = 0; j < lrcAr.length; j++) {if (aud.currentTime >= lrcAr) {cKey = j;if (mKey === j) showLrc(lrcAr);else continue;}}});
aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());
aud.addEventListener('seeked', () => calcKey());
face.addEventListener('click', () => aud.paused ? aud.play() : aud.pause());
</script>


起个网名好难 发表于 2023-3-15 08:04

https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202004%2F12%2F20200412052954_rXsmE.thumb.400_0.gif&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1681430647&t=19db40f1aee564c98514cd47b374de85

马黑黑 发表于 2023-3-15 08:05

CSS和HTML代码未做压缩,便于学习者阅读。这里先简单说说设计思路:

#papa 相关选择器:帖子父元素CSS样式;
#lrc 相关选择器:歌词同步元素CSS样式;
#face 相关选择器:音频播放控制器元素CSS样式。

lrc歌词同步元素,主元素先上歌词,伪元素 ::before 通过宽度的改变覆盖主元素逐一给歌词上色,达到模拟逐字同步的预期。伪元素改变宽度则使用关键帧动画实现,通过JS动态控制。

本帖播放器是脸型播放器,一个父元素face,带三个子元素 span,其中,两个 span 模拟眼睛,一个模拟嘴巴,眼睛和嘴巴各自运行不同的关键帧动画。

帖子共四个关键帧动画:歌词两个,播放器两个,均使用CSS变量 --state 做开关,通过帖子父框 papa 传递开关信息。

小辣椒 发表于 2023-3-15 11:46

哇塞~~居然这么好玩的播放器{:4_170:}

小辣椒 发表于 2023-3-15 11:48

黑神~~威武{:4_178:}

大熊猫都出来了

马黑黑 发表于 2023-3-15 12:33

小辣椒 发表于 2023-3-15 11:48
黑神~~威武

大熊猫都出来了

{:4_172:}

马黑黑 发表于 2023-3-15 12:34

小辣椒 发表于 2023-3-15 11:46
哇塞~~居然这么好玩的播放器

像不像小孩纸的简笔画呢{:5_106:}

红影 发表于 2023-3-15 12:34

这个脸谱播放器好玩,真的像活的一样呢{:4_173:}

马黑黑 发表于 2023-3-15 12:35

起个网名好难 发表于 2023-3-15 08:04


中午好

马黑黑 发表于 2023-3-15 12:36

红影 发表于 2023-3-15 12:34
这个脸谱播放器好玩,真的像活的一样呢

简笔画,和那个有一万行写的真人脸差太远

庶民 发表于 2023-3-15 13:19

熊猫的歌,有趣。

红影 发表于 2023-3-15 16:01

马黑黑 发表于 2023-3-15 12:36
简笔画,和那个有一万行写的真人脸差太远

是两种不同的表现方式啊,这样的简笔画也很好玩的呢{:4_187:}

绿叶清舟 发表于 2023-3-15 17:04

这个好玩

雨中悄然 发表于 2023-3-15 18:02

充满童趣

马黑黑 发表于 2023-3-15 18:08

雨中悄然 发表于 2023-3-15 18:02
充满童趣

{:5_106:}

马黑黑 发表于 2023-3-15 18:08

绿叶清舟 发表于 2023-3-15 17:04
这个好玩

{:4_181:}

马黑黑 发表于 2023-3-15 18:11

红影 发表于 2023-3-15 16:01
是两种不同的表现方式啊,这样的简笔画也很好玩的呢

童趣有

马黑黑 发表于 2023-3-15 18:17

庶民 发表于 2023-3-15 13:19
熊猫的歌,有趣。

感谢支持

红影 发表于 2023-3-15 19:47

马黑黑 发表于 2023-3-15 18:11
童趣有

非常好玩{:4_189:}
页: [1] 2 3 4
查看完整版本: 熊猫之歌