亚伦影音工作室 发表于 2025-11-14 11:35

做你知己陪你一生【克隆小辣椒动图】

本帖最后由 亚伦影音工作室 于 2025-11-14 19:09 编辑 <br /><br /><style>
.blackhole {margin: 10px-300px ;
    position: relative;
    width: 1286px;
    height: 700px;

    background:#222 url(https://img-baofun.zhhainiao.com/pcwallpaper_ugc/live/939ab19eefec994600f8818b05380401.jpg) no-repeat center / cover;
    overflow: hidden;--state: running;
}

#dt{position: absolute;top:0%; left:0%;background-blend-mode:lighten;
        width: 100%;animation: huet 3s linear infinite var(--state);
        height: 100%;z-index: 2; }

#dt img{
        width: 100%;
        height: 100%;}
@keyframes huet{50%{filter:hue-rotate(360deg)contrast(120%)brightness(120%);}}

#qmsvg{ position: absolute;z-index: 8;
      left: 0%;cursor: pointer;
      top: -5%;
       animation: rot 10s linear infinite var(--state);
}
@keyframes rot {0%{ transform: rotate(360deg)scale(0.5);filter: hue-rotate(360deg); }100%{ transform: rotate(0deg)scale(0.5);filter: hue-rotate(0deg); }}

#msvg{position: absolute;background:url(https://pic1.imgdb.cn/item/67aefd3fd0e0a243d4ff2222.png) no-repeat center / cover;border-radius: 50%; top: 47.2%;left: 70.7%;width:90px;height:90px;z-index: 8;animation: move 6s linear infinite var(--state);z-index: 8;cursor: pointer;}
@keyframes move {
                to { transform: rotate(360deg);filter: hue-rotate(360deg); }
        }
.lyrics{margin: 0;
            top: 90%;
            left: 50%;
    transform: translate(-50%, -50%);
            height: 100px; /* 调整高度,只容纳当前歌词 */
                 text-align: center;
            position: absolute;z-index: 10;
      }
            .lyric-line{
            width: 100%;
            position: relative;
            height: 60px;
            overflow: visible;
   font: 200 40px '华文隶书', sans-serif;
            line-height: 60px;
         text-align: left;

            white-space: nowrap; /* 禁止换行 */
            filter: drop-shadow(#fff 1px 0 0) drop-shadow(#fff 0 1px 0) drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px 0);
      }

      .lyric-mask {
            position: absolute;
            top: 0;
            left: 0;
            width: 0;
            overflow: hidden;
      color: #8B4513;
            height: 100%;
            white-space: nowrap;
      }

      .lyric-original {
             color: #ag0000;
            white-space: nowrap;

      }   

#mpic {top:35%; left:-2%;z-index: 10;
display: block;position: absolute;cursor: pointer;
    width: 260px; height: 360px;
    background: url(https://pic1.imgdb.cn/item/68cea8b1c5157e1a88207bd8.png)no-repeat 0px 0/6240px 360px;
animation: burst steps(24) 4s infinite var(--state);
}
@keyframes burst {
0% {background-position: -10px 0;}
100% {background-position: -6240px 0;}
}

#mapic {top:35%; left:80%;z-index: 10;
display: block;position: absolute;cursor: pointer;
    width: 260px; height: 360px;transform: rotateY(180deg);filter: hue-rotate(60deg);
    background: url(https://pic1.imgdb.cn/item/68cea8b1c5157e1a88207bd8.png)no-repeat 0px 0/6240px 360px;
animation: bur steps(24) 4s infinite var(--state);
}
@keyframes bur {
0% {background-position: -10px 0;}
100% {background-position: -6240px 0;}
}

#tmsg {position: absolute;z-index: 6;
      font: normal 14px sans-serif;
      color: #fff;
         bottom: 65%;
      left:38%;}
#fullscreen {
    opacity: 1;
    position: absolute;
    width: 40px;
    height: 40px;
    top:5%;
    cursor: pointer;
    left: 90%;filter:invert(80%) hue-rotate(130deg);
    z-index: 40;
}


#全屏 {
    width: 40px;
    height: 40px;
    position: absolute;

    background: url(https://xlaj.cn/upfile/2025/01/15/dak.png)no-repeat center/cover;
}

#退出 {
    width: 40px;
    height: 40px;
    position: absolute;
    opacity: 0;
    background: url(https://xlaj.cn/upfile/2025/01/15/tz.png)no-repeat center/cover;
}

        </style>
<div class="blackhole">
<div id='dt'><img id="testImg" src="https://wj1.zp68.com:812/lxx/yunhua/2025/11/11/9F.gif" ></div>

<div>
<div id="tmsg">00:00|00:00</div>
<svg id="msvg" width="400" height="400" viewBox="0 0 400 400"></svg>
<svgid="qmsvg"width="200" height="200">

        <defs>
                <path id="path" d="M0 100 A100 100 0 1 1 200 100 A100 100 0 1 1 0 100"/>
        </defs>
        <text dx="30" dy="30" font-size="30" fill="#ffff00"font-family="'楷体'">
                <textPath href="#path" textLength="600">花潮论坛亚伦影音工作室</textPath>
        </text>
</svg>
</div>

<div id="mpic" ></div>
<div id="mapic" ></div>
<div class="lyrics" >
            <div class="lyric-line">
                  <div class="lyric-mask"></div>
                  <div class="lyric-original"></div>
                </div>
            </div>
<span id="fullscreen" title="全屏展示/退出全屏">
<div id="全屏"></div>
    <div id="退出"></div>
</span>
</div>
<audio id="aud" src="https://s2.cldisk.com/sv-w9/audio/69/a8/61/9994adf5fb94283fb6d2fa578f140c67/audio.mp3" loop autoplay></audio>
<script type="module">
        import Dr from 'https://638183.freep.cn/638183/svgdr/svgdr.mod.min.js';
        var dr = Dr.dr(msvg);
       
        var total = 7; // 绘制图案总数
        var points = '200 200,160 65,200 10,240 65,200 200'; // 图案数据

        // 绘制 total 个图案
        Array.from({length: total}).forEach((_,k) => {
                dr.polygon(points, 'none', 'teal', 3).transform(`rotate(${360 / total * k}, 200 200)`);
        });
</script>
<script>
mapic.onclick =mpic.onclick =qmsvg.onclick =msvg.onclick = () => aud.paused ? aud.play() : aud.pause();
        mState = () => blackhole.style.setProperty('--state',aud.paused ? 'paused' : 'running');
aud.onplaying = aud.onpause = () => mState();

(function(){
let mState = () => aud.paused ? image.stop():image.play();
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());
})();
let fs= true;
fullscreen.onclick = () => {
      fs ? (blackhole.requestFullscreen(),全屏.style.opacity= '0',退出.style.opacity = '1') : ( document.exitFullscreen(),全屏.style.opacity = '1',退出.style.opacity = '0');
      fs = !fs;
}
const blackhole= document.querySelector('.blackhole');

aud.addEventListener('timeupdate', () => {
            tmsg.innerText = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
      });

      function toMin(val) {
            if (!val) return '00:00';
            val = Math.floor(val);
            let min = parseInt(val / 60);
            let sec = parseFloat(val % 60);
            if (min < 10) min = '0' + min;
            if (sec < 10) sec = '0' + sec;
            return min + ':' + sec;
      }
</script>
<script>
      // 歌词解析ksc歌词或lrc歌词
      const lrc = `做你知己陪你一生
演唱:金钰儿
作词:未子夫
作曲:谢世超
混音:王哲
监制:徐佩佩
统筹:池歌
出品 亚伦影音工作室
演唱:金钰儿
如果那个对的人
出现在错的时分
到底是种幸运还是一种残忍
自从我遇见你的眼神
每过一天 思念就多一分
尽管我无法和你
看每个日出黄昏
依然无怨无悔对你一往情深
我默默心疼 你的心疼
用心治愈 你所有的伤痕
就算只做知己 陪你一生
我也愿意为你 痴痴地等
陪你看风雨 陪你安稳
用我的方式陪伴你的余生
做你红尘知己 陪你一生
哪怕分隔两座 不同的城
不管你我有没有可能
你是心底最温柔的部分
尽管我无法和你
看每个日出黄昏
依然无怨无悔对你一往情深
我默默心疼 你的心疼
用心治愈 你所有的伤痕
就算只做知己 陪你一生
我也愿意为你 痴痴地等
陪你看风雨 陪你安稳
用我的方式陪伴你的余生
做你红尘知己 陪你一生
哪怕分隔两座 不同的城
不管你我有没有可能
你是心底最温柔的部分
你是心底最温柔的部分
`;

      const lyrics = parseLyrics(lrc);
      const lyricMask = document.querySelector('.lyric-mask');
      const lyricOriginal = document.querySelector('.lyric-original');

      let currentIndex = -1;
      let currentLyric = null;

      // 解析歌词(支持两种格式)
      function parseLyrics(lrcText) {
            const lyrics = [];
            if (lrcText.includes('karaoke.add')) {
                const lineRegex = /karaoke\.add\('([^']+)', '([^']+)', '([^']+)', '([^']+)'\);/g;
                let match;
                while ((match = lineRegex.exec(lrcText)) !== null) {
                  const startTime = timeToMs(match);
                  const endTime = timeToMs(match);
                  const text = match.replace(/\[|\]/g, '').trim();
                  const durations = match.split(',').map(Number);
                  if (text) {
                        lyrics.push({startTime, endTime, text, durations});
                  }
                }
            }
            else if (lrcText.includes('[')) {
                const lines = lrcText.split('\n').filter(line => line.trim());
                lines.forEach((line, index) => {
                  const timeMatch = line.match(/\[(\d+:\d+\.\d+)\]/);
                  if (timeMatch) {
                        const timeStr = timeMatch;
                        const text = line.replace(/\[.*?\]/, '').trim();
                        if (text) {
                            const startTime = timeToMs(timeStr);
                            const nextLine = lines;
                            const nextTimeMatch = nextLine ? nextLine.match(/\[(\d+:\d+\.\d+)\]/) : null;
                            const endTime = nextTimeMatch ? timeToMs(nextTimeMatch) : startTime + 5000;
                            lyrics.push({
                              startTime,
                              endTime,
                              text,
                              durations: calculateCharDurations(text, startTime, endTime)
                            });
                        }
                  }
                });
            }
            return lyrics;
      }
      function calculateCharDurations(text, startTime, endTime) {
            const totalDuration = endTime - startTime;
            const charCount = text.length;
            const baseDur = Math.floor(totalDuration / charCount);
            const durations = new Array(charCount).fill(baseDur);
            const remainder = totalDuration % charCount;
            for (let i = 0; i < remainder; i++) {
                durations++;
            }
            return durations;
      }
      function timeToMs(timeStr) {
            const parts = timeStr.split(':');
            const minutes = parseInt(parts, 10);
            const secondsAndMs = parts.split('.');
            const seconds = parseInt(secondsAndMs, 10);
            const ms = parseInt(secondsAndMs || 0, 10);
            return minutes * 60 * 1000 + seconds * 1000 + ms;
      }
      function getCurrentLyricIndex(lyrics, currentTimeMs) {
            for (let i = 0; i < lyrics.length; i++) {
                if (currentTimeMs >= lyrics.startTime && currentTimeMs <= lyrics.endTime) {
                  return i;
                }
            }
            return -1;
      }
      function updateLyricDisplay(index) {
            if (index < 0 || index >= lyrics.length) return;
            currentIndex = index;
            currentLyric = lyrics;
            lyricOriginal.textContent = currentLyric.text;
            lyricMask.textContent = currentLyric.text;
            lyricMask.style.width = '0%';
      }
      function updateLyricMask(currentTimeMs) {
            if (!currentLyric) return;
            const lyricStartTime = currentLyric.startTime;
            const elapsed = currentTimeMs - lyricStartTime;
            const totalDuration = currentLyric.durations.reduce((sum, d) => sum + d, 0);
            let charIndex = 0;
            let accumulatedTime = 0;

            for (let i = 0; i < currentLyric.durations.length; i++) {
                accumulatedTime += currentLyric.durations;
                if (elapsed <= accumulatedTime) {
                  charIndex = i + 1;
                  break;
                }
            }

            if (elapsed >= totalDuration) {
                charIndex = currentLyric.text.length;
            }

            charIndex = Math.min(charIndex, currentLyric.text.length);

            const tempSpan = document.createElement('span');
            tempSpan.style.visibility = 'hidden';
            tempSpan.style.position = 'absolute';
            tempSpan.style.fontSize = '50px';
            tempSpan.style.fontWeight = '800';
            document.body.appendChild(tempSpan);

            const visibleText = currentLyric.text.substring(0, charIndex);
            tempSpan.textContent = visibleText;
            const width = tempSpan.offsetWidth;
            document.body.removeChild(tempSpan);

            lyricMask.style.width = `${width}px`;
      }

      // 监听更新歌词
      aud.addEventListener('timeupdate', () => {
            const currentTimeMs = aud.currentTime * 1000;
            const index = getCurrentLyricIndex(lyrics, currentTimeMs);

            if (index !== currentIndex) {
                updateLyricDisplay(index);
            }

            updateLyricMask(currentTimeMs);
      });
      updateLyricDisplay(0);
</script>


<script>
if ('getContext' in document.createElement('canvas')) {
    HTMLImageElement.prototype.play = function() {
      if (this.storeCanvas) {
            // 移除存储的canvas
            this.storeCanvas.parentElement.removeChild(this.storeCanvas);
            this.storeCanvas = null;
            // 透明度还原
            image.style.opacity = '';
      }
      if (this.storeUrl) {
            this.src = this.storeUrl;   
      }
    };
    HTMLImageElement.prototype.stop = function() {
      var canvas = document.createElement('canvas');
      // 尺寸
      var width = this.width, height = this.height;
      if (width && height) {
            // 存储之前的地址
            if (!this.storeUrl) {
                this.storeUrl = this.src;
            }
            // canvas大小
            canvas.width = width;
            canvas.height = height;
            // 绘制图片帧(第一帧)
            canvas.getContext('2d').drawImage(this, 0, 0, width, height);
            // 重置当前图片
            try {
                this.src = canvas.toDataURL("image/gif");
            } catch(e) {
                // 跨域
                this.removeAttribute('src');
                // 载入canvas元素
                canvas.style.position = 'absolute';
                // 前面插入图片
                this.parentElement.insertBefore(canvas, this);
                // 隐藏原图
                this.style.opacity = '0';
                // 存储canvas
                this.storeCanvas = canvas;
            }
      }
    };
}
var image = document.getElementById("testImg");
</script>


偶然~ 发表于 2025-11-14 15:08

这个播放器大气

偶然~ 发表于 2025-11-14 15:08

歌曲动听

偶然~ 发表于 2025-11-14 15:09

感谢亚伦影音工作室带来的精彩,辛苦了!祝您创作如春泉涌流不息!

杨帆 发表于 2025-11-14 15:28

切换顺畅,效果惊艳,谢谢亚伦老师精彩分享{:4_191:}

红影 发表于 2025-11-14 19:32

还把背景变成了变色背景,这制作真漂亮。
欣赏亚伦老师好帖{:4_199:}
页: [1]
查看完整版本: 做你知己陪你一生【克隆小辣椒动图】