马黑黑 发表于 2022-10-12 07:14

秋日恋歌

<style>
#papa { left: -214px; width: 1024px; height: 640px; background: gray url('https://638183.freep.cn/638183/t22/webp/qrlg.webp') no-repeat center/cover; box-shadow: 3px 3px 20px #000; display: grid; place-items: center; overflow: hidden; user-select: none; position: relative; z-index: 1; }
.btnplay { position: absolute; top: 0px; left: 100px; width: 80px; height: 80px; border-radius: 50%; box-shadow: 15px 10px 0 0 orange; cursor: pointer; z-index: 10; animation: swing 1s linear infinite alternate; }
.btnplay::before { position: absolute; content: ''; left: 20px; top: 12px; width: 100%; height: 100%; }
.btnplay::after { position: absolute; content: ''; left: 25px; top: 25px; width: 40%; height: 40%; border-radius: 50%; background: tan; box-shadow: 0 0 30px 0px purple, 0 0 100px 0 snow; }
#lrc { --motion: cover1; --tt: 1s; --state: paused; position: absolute; bottom: 15px; font: bold 2.4em sans-serif; color: hsl(60,100%,90%); -webkit-background-clip: text; filter: drop-shadow(1px 1px 2px hsla(0,100%,0%,.85)); }
#lrc::before { position: absolute; content: attr(data-lrc); width: 20%; height: 100%; color: transparent; overflow: hidden; white-space: nowrap; background: linear-gradient(180deg,hsla(0,100%,50%,.75),hsla(60,100%,50%,.65)); filter: inherit; -webkit-background-clip: text; animation: var(--motion) var(--tt) linear forwards; animation-play-state: var(--state); }
#svg { position: absolute; font: bold 10em sans-serif; }
.text { fill: none; stroke-width: 3; stroke-dasharray: 0 300; stroke-dashoffset: 0; }
.text:nth-child(3n + 1) { stroke: orange; animation: stroke1 30s ease-in-out infinite alternate; }
.text:nth-child(3n + 2) { stroke: red; animation: stroke2 30s ease-in-out infinite alternate; }
.text:nth-child(3n + 3) { stroke: snow; animation: stroke3 30s ease-in-out infinite alternate; }
.text:hover { fill: teal; opacity: .45; }
@keyframes cover1 { from { width: 0; } to { width: 100%; } }
@keyframes cover2 { from { width: 0; } to { width: 100%; } }
@keyframes swing { from { transform: rotate(0deg); } to { transform: rotate(30deg); } }
@keyframes stroke1 { to { stroke-dashoffset: 1000; stroke-dasharray: 80 160; } }
@keyframes stroke2 { to { stroke-dashoffset: 1080; stroke-dasharray: 80 160; } }
@keyframes stroke3 { to { stroke-dashoffset: 1160; stroke-dasharray: 80 160; } }
</style>

<div id="papa">
        <svg id="svg" width="1024" height="640">
                <symbol id="s-text"><text text-anchor="middle" x="50%" y="50%" dy=".35em">秋日恋歌</text></symbol>
                <use xlink:href="#s-text" class="text"></use>
                <use xlink:href="#s-text" class="text"></use>
                <use xlink:href="#s-text" class="text"></use>
        </svg>
        <span class="btnplay" title="播放/暂停"></span>
        <span style="position: absolute; transform: rotate(270deg); bottom: -120px; left: 80px; ">
                <span class="btnplay" style="filter:blur(3px); opacity: .45; cursor: default;"></span>
        </span>
        <span id="lrc" data-lrc="花潮论坛lrc在线">花潮论坛lrc在线</span>
</div>

<script>
(function() {
        let mKey = 0, mFlag = true, aud = new Audio();
        let lrcAr = [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,];
        let btnplay = document.querySelector('.btnplay');
        aud.src = 'https://music.163.com/song/media/outer/url?id=26147208.mp3';
        aud.loop = false;
        aud.play();
        btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
        aud.addEventListener('pause', () => mState());
        aud.addEventListener('play', () => mState());
        aud.addEventListener('ended', () => { mKey = 0; aud.play(); });
        aud.addEventListener('timeupdate', () => {for (j = 0; j < lrcAr.length; j++) {if (aud.currentTime >= lrcAr) {if (mKey === j) showLrc(lrcAr);else continue;}}});
        let mState = () => aud.paused ? (btnplay.style.animationPlayState = 'paused', lrc.style.setProperty('--state', 'paused')) : (btnplay.style.animationPlayState = 'running', lrc.style.setProperty('--state', 'running'));
        let showLrc = (time) => {let name = mFlag ? 'cover1' : 'cover2';lrc.innerHTML = lrc.dataset.lrc = lrcAr;lrc.style.setProperty('--motion', name);lrc.style.setProperty('--tt', time + 's');lrc.style.setProperty('--state', 'running');mKey += 1;mFlag = !mFlag;};
})();
</script>

马黑黑 发表于 2022-10-12 07:19

本帖最后由 马黑黑 于 2022-10-12 07:37 编辑

帖子中央的文本特效,用CSS+svg实现,代码如下:

一、CSS

#svg {
      position: absolute;
      font: bold 10em sans-serif; /* 字体 */
}

.text {
      fill: none; /* 无填充色 */
      stroke-width: 3; /* 描边宽度 */
      stroke-dasharray: 0 300; /* 描边线段样式 */
      stroke-dashoffset: 0; /* 描边线段偏移 */
}

/* 1、4、7 ... 单字样式 - 3n + 1 ,n 从 0 开始 */
.text:nth-child(3n + 1) {
      stroke: orange; /* 描边色 */
      animation: stroke1 30s ease-in-out infinite alternate; /* 运行关键帧动画 */
}

/* 2、5、8 ... 单字样式 */
.text:nth-child(3n + 2) {
      stroke: red;
      animation: stroke2 30s ease-in-out infinite alternate;
}

/* 3、6、9 ... 单字样式 */
.text:nth-child(3n + 3) {
      stroke: snow;
      animation: stroke3 30s ease-in-out infinite alternate;
}

/* 鼠标滑过文本时 */
.text:hover {
      fill: teal; /* 文本填充色 */
      opacity: .45; /* 透明设置 */
}

/**下面三个关键帧动画,依次对应 147、258、369顺序的单字
虚线线段样式 stroke-dasharray 从前面设定的 0 300 变化到下面的 80 160
虚线线段偏移量 stroke-dashoffse 从前面设定的 0 到 1000、1080、1160
关键帧动画其实用一个就好,但需要用到变量,生怕大家看花眼,所以一个一个来
**/
@keyframes stroke1 {
      to {
                stroke-dashoffset: 1000;
                stroke-dasharray: 80 160;
      }
}

@keyframes stroke2 {
      to {
                stroke-dashoffset: 1080;
                stroke-dasharray: 80 160;
      }
}

@keyframes stroke3 {
      to {
                stroke-dashoffset: 1160;
                stroke-dasharray: 80 160;
      }
}

二、HTML

<svg id="svg" width="1024" height="640">
      <symbol id="s-text"><text text-anchor="middle" x="50%" y="50%" dy=".35em">秋日恋歌</text></symbol>
      <use xlink:href="#s-text" class="text"></use>
      <use xlink:href="#s-text" class="text"></use>
      <use xlink:href="#s-text" class="text"></use>
</svg>

svg代码不多做解释,好奇的朋友如果有不解,可取查一下 symbol 和 use,这两货是此处的功臣。



马黑黑 发表于 2022-10-12 07:48

本帖最后由 马黑黑 于 2022-10-12 07:50 编辑

播放控制器使用单标签实现,但CSS代码比较多:

/* 按钮 */
.btnplay {
      position: absolute;
      top: 0px;
      left: 100px;
      width: 80px;
      height: 80px;
      border-radius: 50%;
      box-shadow: 15px 10px 0 0 orange;
      cursor: pointer;
      z-index: 10;
      animation: swing 1s linear infinite alternate;
}
/* 伪元素一:用以调整鼠标点击的接收区域 */
.btnplay::before {
      position: absolute;
      content: '';
      left: 20px;
      top: 12px;
      width: 100%;
      height: 100%;
}
/* 伪元素二:模拟伴星 */
.btnplay::after {
      position: absolute;
      content: '';
      left: 25px;
      top: 25px;
      width: 40%;
      height: 40%;
      border-radius: 50%;
      background: tan;
      box-shadow: 0 0 30px 0px purple, 0 0 100px 0 snow;
}

/* 关键帧动画:摇摆 */
@keyframes swing {
      from { transform: rotate(0deg); }
      to { transform: rotate(30deg); }
}


HTML就一个标签代码:

      <span class="btnplay" title="播放/暂停"></span>

JS中,播放器状态控制函数里,设置一下动画的暂停与继续:

let mState = () => aud.paused ? (btnplay.style.animationPlayState = 'paused', lrc.style.setProperty('--state', 'paused')) : (btnplay.style.animationPlayState = 'running', lrc.style.setProperty('--state', 'running'));

这个函数的运行,有诸多触发节点,比如按钮的点击、歌曲能不能自动播放、歌曲是播放中还是暂停中等等,都通过对播放器的监测实现,这里不多做解释。监控代码在这两行:

      aud.addEventListener('pause', () => mState());
      aud.addEventListener('play', () => mState());


马黑黑 发表于 2022-10-12 07:56

播放器再左下角水中的投影,是对左上角按钮控制器的二次利用,用一个标签将其包裹起来以便易于控制它的位置和动作:

        <span style="position: absolute; transform: rotate(270deg); bottom: -120px; left: 80px; ">
                <span class="btnplay" style="filter:blur(3px); opacity: .45; cursor: default;"></span>
        </span>


包裹的外标签,居中定义了样式(绿色代码),同样,引用按钮控制器的代码,也用了句内的临时样式(红色代码)。

上海朝阳 发表于 2022-10-12 08:44

这字幕太精妙了,兼容看是日月相伴,极速打开,山水屏幕出来了,那些像萤火虫慢慢跑动起来,隐隐约约的主题出来了。唱者是水木年华中的一个

红影 发表于 2022-10-12 09:05

这个svg文字漂亮,还能往复进行动画效果,非常惊艳{:4_199:}

红影 发表于 2022-10-12 09:08

马黑黑 发表于 2022-10-12 07:56
播放器再左下角水中的投影,是对左上角按钮控制器的二次利用,用一个标签将其包裹起来以便易于控制它的位置 ...

transform: rotate(270deg); 这个和上次动图的投影不一样呢。

红影 发表于 2022-10-12 09:33

关于月牙怎么出来的,又迷糊了,还得去翻前面的帖子才行{:4_173:}

梦油 发表于 2022-10-12 11:08

哇!“秋日恋歌”这几个字设计得太漂亮啦。

醉美水芙蓉 发表于 2022-10-12 11:49

马黑黑 发表于 2022-10-12 13:26

醉美水芙蓉 发表于 2022-10-12 11:49
黑黑老师这个播放器真漂亮!

还行吧

马黑黑 发表于 2022-10-12 13:31

红影 发表于 2022-10-12 09:08
transform: rotate(270deg); 这个和上次动图的投影不一样呢。

方法多了去,看爱用什么

马黑黑 发表于 2022-10-12 13:31

上海朝阳 发表于 2022-10-12 08:44
这字幕太精妙了,兼容看是日月相伴,极速打开,山水屏幕出来了,那些像萤火虫慢慢跑动起来,隐隐约约的主题 ...

现在都不考虑兼容IE了,IE早已宣布死亡

马黑黑 发表于 2022-10-12 13:32

梦油 发表于 2022-10-12 11:08
哇!“秋日恋歌”这几个字设计得太漂亮啦。

还行

马黑黑 发表于 2022-10-12 13:32

红影 发表于 2022-10-12 09:33
关于月牙怎么出来的,又迷糊了,还得去翻前面的帖子才行

用影子

马黑黑 发表于 2022-10-12 13:32

红影 发表于 2022-10-12 09:05
这个svg文字漂亮,还能往复进行动画效果,非常惊艳

过得去吧。原理和前面弄过的差别不大。

梦油 发表于 2022-10-12 14:52

马黑黑 发表于 2022-10-12 13:32
还行

黑黑朋友真谦逊。

红影 发表于 2022-10-12 15:54

马黑黑 发表于 2022-10-12 13:31
方法多了去,看爱用什么

嗯嗯,在黑黑的帖子里慢慢学习{:4_187:}

红影 发表于 2022-10-12 15:55

马黑黑 发表于 2022-10-12 13:32
用影子

我知道是用投影,一下子又有点反应不过来了。

红影 发表于 2022-10-12 15:55

马黑黑 发表于 2022-10-12 13:32
过得去吧。原理和前面弄过的差别不大。

是的,你在歌词里也弄过的呢。
页: [1] 2 3 4 5 6 7
查看完整版本: 秋日恋歌