杨帆 发表于 2025-7-18 22:01

《满江红》- 学习马老师和亚伦老师帖代码

本帖最后由 杨帆 于 2025-7-18 22:16 编辑 <br /><br /><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>满江红</title>
</head>
<body>
<style>
    #tz { position: relative; margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1400px); min-height: auto; aspect-ratio: 16/9; overflow: hidden; box-shadow: 0px 0px 1px 1px #fff, 0px 0px 1px 2px #000; background: #666 url('https://pic1.imgdb.cn/item/6879419758cb8da5c8bf109a.webp') no-repeat center/cover; user-select: none; z-index: 2; }
    #papa { margin: 0px 0px; width: 100%; height: 100%; background: url(https://pic1.imgdb.cn/item/6879419758cb8da5c8bf109a.webp) no-repeat center/cover; overflow: hidden; z-index: 1; position: absolute; }
    #papa > canvas { position: absolute; left: 0; top: 0; right: 0; bottom: 0; display: block; }
    #enopg, #cndpt, #zuo, #you { transition: 3s; }
    #enopg { position: absolute; width: 100%; height: 100%; background: url(https://pic1.imgdb.cn/item/68790ea758cb8da5c8bef062.gif) no-repeat center/cover; clip-path: polygon(0 0, 50% 0, 50% 50%, 50% 50%, 0 50%); transform: translate(0%, 0%); }
    #cndpt { position: absolute; width: 100%; height: 100%; background: url(https://pic1.imgdb.cn/item/68790ea758cb8da5c8bef062.gif) no-repeat center/cover; clip-path: polygon(100% 100%, 50% 100%, 50% 50%, 50% 50%, 100% 50%); transform: translate(0%, 0%); }
    #zuo { position: absolute; width: 100%; height: 100%; background: url(https://pic1.imgdb.cn/item/68790ea758cb8da5c8bef062.gif) no-repeat center/cover; transform: translate(0%, 0%); clip-path: polygon(100% 0, 50% 0, 50% 50%, 50% 50%, 100% 50%); }
    #you { position: absolute; width: 100%; height: 100%; background: url(https://pic1.imgdb.cn/item/68790ea758cb8da5c8bef062.gif) no-repeat center/cover; transform: translate(0%, 0%); clip-path: polygon(0 100%, 50% 100%, 50% 50%, 50% 50%, 0 50%); }
    #but { margin: 0% 0%; width: 100%; height: 100%; position: absolute; cursor: pointer; z-index: 2; }
    .lzpa { perspective-origin: 0% 0%; }
    li-zi { --size: 35px; background: url('https://638183.freep.cn/638183/t23/btn/dou.png') no-repeat center/cover; opacity: 1; animation: fadein 3s var(--delay) ease-in-out infinite alternate var(--state); }
    .player { background: url('https://pic1.imgdb.cn/item/686fd0eb58cb8da5c89ab521.png') no-repeat center/cover; width: 100px; height: 100px; position: absolute; top:28%; left: 50%; cursor: pointer; z-index: 2; }
    #vid1 { position: absolute; width: 100%; height: 100%; object-fit: cover; mask: linear-gradient(to right top, red 0%, transparent 60%, transparent); -webkit-mask: linear-gradient(to right top, red 0%, transparent 60%, transparent); opacity: .75; pointer-events: none; }
    #vid2 { position: absolute; width: 100%; height: 100%; object-fit: cover; mask: radial-gradient(transparent 20%, red); -webkit-mask: radial-gradient(transparent 20%, red); opacity: .75; pointer-events: none; }
    #lrc { left: 10%; top: 15%; }
    #lrcc { left: 90%; transform: translate(-102%); top: 20%; }
    #lrc, #lrcc { --state: paused; --motion: cover2; --tt: 2s; --bg: linear-gradient(89deg, #EE0000 12%, #078504 35%, #060344 65%, #DE0000 90%); border: 0px solid black; position: absolute; z-index: 6; font: normal 3.2em 华文新魏; color: #222222; white-space: pre; -webkit-background-clip: text; filter: drop-shadow(#ffffff 1px 0 0) drop-shadow(#ffffff 0 1px 0) drop-shadow(#ffffff -1px 0 0) drop-shadow(#ffffff 0 -1px 0); z-index: 1; }
    #lrcc::before, #lrc::before { position: absolute; content: attr(data-lrc); width: 100%; height: 100%; color: transparent; overflow: hidden; white-space: pre; background: var(--bg); clip-path: inset(0% 100% 0 0); -webkit-background-clip: text; animation: var(--motion) var(--tt) linear forwards; animation-play-state: var(--state); }
    @keyframes cover1 { to { clip-path: inset(0 0% 0 0); } }
    @keyframes cover2 { to { clip-path: inset(0 0 0 0); } }
    #Img { position: absolute; mix-blend-mode: darken; left: 30%; top: 1%; background: none; z-index: 1; }
    #fullscreen { border-radius: 4px; position: absolute; background: #0000; color: #fff; box-shadow: 0px 0px 0px 1px #fff; z-index: 20; padding: 4px 10px; font-size: 12px; border: none; cursor: pointer; margin: 8px 5px; left: 90%; top: 3%; }
</style>
<div id="tz">
    <span id="fullscreen" title="">全屏欣赏</span>
    <div id="but" title="进入/关闭">
      <div id="cndpt"></div>
      <div id="zuo"></div>
      <div id="you"></div>
      <div id="enopg"></div>
    </div>
    <div id="papa">
      <audio id="aud" src="https://upfile.mp3.wf/view.php/5e96169c7fb6f624d9697a4d5bc41f62.mp3" loop></audio>
      <video id="vid1" src="https://img.tukuppt.com/video_show/2269348/00/14/17/5e1c8201ef2f7.mp4" autoplay loop
      muted></video>
      <video id="vid2" src="https://bpic.588ku.com/video_listen/588ku_video/25/04/08/17/14/59/video67f4e91361a39.mp4"
      autoplay loop muted></video>
      <div class="player" title="播放/暂停"></div>
      <div id="lrc" data-lrc=""></div>
      <div id="lrcc" data-lrc=""></div>
    </div>
    <img id="Img" src="https://cccimg.com/view.php/cd45d90af69ff09386f4c19dfb3650c0.gif"
      style="width: 605px; height: 334px;" alt="" />
</div>
<script type="module">
    import { lz } from 'https://638183.freep.cn/638183/web/js/3dcsslz.js';
    lz(papa, { total: 30, step: 0.25, hue: 120, delay: -3 });
</script>
<span id="lrcStr" style="visibility: hidden;">
    满江红 - 杨洪基
    词:岳飞
    曲:顾嘉煇
    怒发冲冠 凭阑处
    潇潇雨歇
    抬望眼 仰天长啸
    壮怀激烈
    三十功名尘与土
    八千里路云和月
    莫等闲 白了少年头
    空悲切
    靖康耻犹未雪
    臣子憾 何时灭
    驾长车
    踏破贺兰山缺
    壮志饥餐胡虏肉
    笑谈渴饮匈奴血
    待从头 收拾旧山河
    朝天阙
</span>
<script>
    (function () {
      /*变量 :mKey - 当前歌词索引;averAdd :平均值补偿*/
      let mKey = 0, averAdd = 0.3;
      /*获取DOM元素*/
      const aud = document.getElementById('aud');
      const player = document.querySelector('.player');
      const vid1 = document.getElementById('vid1');
      const vid2 = document.getElementById('vid2');
      const Img = document.getElementById('Img');
   
      player.addEventListener('click', () => {
      if (aud.paused) {
          aud.play();
      } else {
          aud.pause();
      }
      });

      /*函数 :获取每句歌词用时,歌词用时若超过平均值则取平均值,最后一句歌词则取平均值*/
      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;
      };

      /*函数 :从原始lrc歌词获取信息并存入 n*3 数组*/
      let getLrcAr = (text) => {
      let lrcAr = [];
      let arr = "";
      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) => {
      lrca = lrcAr;
      lrcAr.length == mKey + 1 ? lrcb = "" : lrcb = lrcAr;//判断最后一句歌词
      let Y = String(mKey / 2).indexOf(".");
      if (Y == -1) {
          0 == mKey && (lrc.innerHTML = lrca);
          lrc.dataset.lrc = lrca;
          lrcc.innerHTML = lrcb;
          lrcc.dataset.lrc = "";
          lrc.style.setProperty('--motion', 'cover1');
          lrc.style.setProperty('--tt', time + 's');
          lrc.style.setProperty('--state', 'running');
          lrcc.style.setProperty('--motion', 'cover2');
      } else {
          lrc.innerHTML = lrcb;
          lrcc.dataset.lrc = lrca;
          lrc.dataset.lrc = "";
          lrcc.style.setProperty('--motion', 'cover1');
          lrcc.style.setProperty('--tt', time + 's');
          lrcc.style.setProperty('--state', 'running');
          lrc.style.setProperty('--motion', 'cover2');
      }
      mKey += 1;
      };
      /*函数 :处理当前歌词索引 mKey*/
      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 = () => {
      // 控制歌词动画状态
      aud.paused ? (lrc.style.setProperty("--state", "paused"), lrcc.style.setProperty("--state", "paused")) :
          (lrc.style.setProperty("--state", "running"), lrcc.style.setProperty("--state", "running"));

      Img.style.display = aud.paused ? 'none' : '';

      if (aud.paused) {
          vid1.pause();
          vid2.pause();
      } else {
          vid1.play();
          vid2.play();
      }
      };

      /*监听播放进度*/
      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());/*监听查询事件*/

      let lrcAr = getLrcAr(lrcStr.innerHTML); /*获得歌词数组*/
    })();

    but.onclick = () => aud.paused ? (aud.play(), enopg.style.transform = 'translate(-100%, -100%)', cndpt.style.transform = 'translate(100%, 100%)', zuo.style.transform = 'translate(100%, -100%)', you.style.transform = ' translate(-100%, 100%)') : (aud.pause(), enopg.style.transform = 'translate(0%, 0%)', cndpt.style.transform = 'translate(0%, 0%)', zuo.style.transform = 'translate(0%, 0%)', you.style.transform = 'translate(0%, 0%)');

    let fs = true;
    fullscreen.onclick = () => {
      if (fs) {
      fullscreen.innerText = '退出全屏';
      tz.requestFullscreen();
      } else {
      fullscreen.innerText = '全屏欣赏';
      document.exitFullscreen();
      }
      fs = !fs;
    };

</script>
</body>
</html>

红影 发表于 2025-7-18 22:22

漂亮。点击后可以进入一个活泼的世界了。
粒子选择很漂亮。那个小播最奇特,好像变成多个重叠在一起的转动似的。
欣赏杨帆好帖{:4_199:}

杨帆 发表于 2025-7-18 22:25

红影 发表于 2025-7-18 22:22
漂亮。点击后可以进入一个活泼的世界了。
粒子选择很漂亮。那个小播最奇特,好像变成多个重叠在一起的转动 ...

谢谢影子鼓励,周末愉快{:4_187:}

红影 发表于 2025-7-18 22:32

杨帆 发表于 2025-7-18 22:25
谢谢影子鼓励,周末愉快

这个场景很有立体感呢,制作十分漂亮{:4_199:}

梦江南 发表于 2025-7-19 07:32

好设计!厉害!结合了开场,运用黑黑老师的代码,再加上了歌词。太棒了!{:4_187:}

杨帆 发表于 2025-7-19 16:07

梦江南 发表于 2025-7-19 07:32
好设计!厉害!结合了开场,运用黑黑老师的代码,再加上了歌词。太棒了!

问好江南,谢谢鼓励,周末愉快{:4_187:}
页: [1]
查看完整版本: 《满江红》- 学习马老师和亚伦老师帖代码