小辣椒 发表于 2025-10-27 23:22

听心 (经典版) - 魏佳艺

本帖最后由 小辣椒 于 2025-10-27 23:24 编辑 <br /><br /><style>
#papa {margin: 120px -230px;
width: 1286px;
height: 720px;
border: 0px solid gray;
background:radial-gradient(ellipse farthest-corner at center center, transparent 38%,#999 90%),url(https://wj.zp68.com/lxx/yunhua/2025/10/06/04.jpg),linear-gradient(135deg, #e56420, #c22525, #3d9c31, #000078);
overflow: hidden;
position: relative;
--state: running;
}

.k-container-body {margin: 180px 390px;
position: absolute;transform:rotatey(0deg);
background: linear-gradient(45deg,
                #000078, #000, #880000, #00aa00, #00aa7f, #111111, #00bb00, #ff0000);
border: 3px solid #d0d0d0;
border-radius: 20px;
width: 550px;
height: 320px;
perspective: 10000;
padding: 10px;overflow: hidden;
}
.k-container-body:before,
.k-container-body:after {
content: '';
position: absolute;
bottom: 20px;
height: 90px;
width: 35px;
border-radius: 10px;
z-index: -1;
}
.k-container-body:before {
border-left: 3px solid #d0d0d0;
left: -12px;
}
.k-container-body:after {
border-right: 3px solid #d0d0d0;
right: -12px;
}
.k-screw {
position: absolute;
display: inline-block;
border: 1px solid #d0d0d0;
border-radius: 50%;
width: 14px;
height: 14px;
}
.k-screw:before,
.k-screw:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform-origin: center;
background-color: #d0d0d0;
height: 70%;
width: 2px;
}
.k-screw:before {
transform: translate(-50%, -50%) rotate(90deg);
}
.body .k-screw:after {
transform: translate(-50%, -50%) rotate(-90deg);
}
.k-screw.top-left {transform:rotateZ(12deg);
top: 7px;
left: 7px;
}
.k-screw.top-right {transform:rotateZ(-5deg);
top: 7px;
right: 7px;
}
.k-screw.bottom-left {transform:rotateZ(8deg);
bottom: 7px;
left: 7px;
}
.k-screw.bottom-right {transform:rotateZ(-10deg);
bottom: 7px;
right: 7px;
}
.k-centerreel {box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 3px solid #d0d0d0;
border-radius: 45px;
width: 300px;
height: 90px;background: linear-gradient(45deg,
                #000078, #000, #ff0000, #ffd700, #00aa7f, #111111, #999999, #000080);
padding: 10px;
}
.k-centerreel .reel {
position: relative;
display: inline-block;
border: 2px solid #d0d0d0;
width: 65px;
height: 100%;
border-radius: 50%;
}
.k-centerreel .reel:before {
content: '';
display: inline-block;
width: 82%;
height: 82%;
border: 6px dashed #d0d0d0;
border-radius: 50%;
transform-origin: center;
animation: spin 3s linear infinite var(--state);
}
.k-centerreel .reel.left {
float: left;
}
.k-centerreel .reel.right {
float: right;
}
.k-centerreel .center-tape {
border: 2px solid #d0d0d0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 70%;
width: 100px;
border-radius: 10px;
overflow: hidden;
}
.k-centerreel .center-tape:before {
content: '';
border: 3px solid #d0d0d0;
border-radius: 50%;
width: 80px;
height: 80px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: -50%;
animation: shiftLeft 1.3s ease-in-out alternate infinite var(--state);
}
.k-centerreel .center-tape:after {
content: '';
border: 3px solid #d0d0d0;
border-radius: 50%;
width: 100px;
height: 100px;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: -95%;
animation: shiftRight 1s ease-in-out alternate infinite var(--state);
}
.k-label {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #d0d0d0;
top: 25%;
max-width: 400px;
width: 100%;
padding: 0px 20px;
overflow: hidden;
}
.k-label:before {
content: '';
position: absolute;
bottom: 1.85ex;
left: 0;
right: 0;
height: 2.5ex;
border-top: 1px dashed #d0d0d0;
border-bottom: 3px dashed #d0d0d0;
z-index: -1;
}

.k-chin {
position: absolute;
left: 10%;
bottom: -6px;
transform:perspective(1em) rotateX(3deg);
transform-origin: bottom center;
max-width: 450px;
width: 100%;
height: 120px;background: linear-gradient(45deg,
                #000078, #000, #ff0000, #ffd700, #00aa7f, #111111, #999999, #000080);
border-radius: 5px;
font-size: 60px;
   border: 2px solid #d0d0d0;
}

.k-chin:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
top: 30%;
background: #eee;
width: 10px;
height: 10px;
border-radius: 20%;
}
.k-chin .holes {transform:rotateX(-65deg);
position: absolute;
display: inline-block;
border: 3px solid #d0d0d0;
border-radius: 20%;
}
.k-chin .holes:nth-child(1) {
width: 15px;
height: 20px;
bottom: 15px;
left: 40px;
}
.k-chin .holes:nth-child(2) {
width: 10px;
height: 20px;
bottom: 50px;
left: 80px;
}
.k-chin .holes:nth-child(3) {
width: 10px;
height: 20px;
bottom: 50px;
right: 80px;
}
.k-chin .holes:nth-child(4) {
width: 15px;
height: 20px;
bottom: 15px;
right: 40px;
}

@keyframes spin {
0% {
    transform: rotate(0deg);
}
100% {
    transform: rotate(360deg);
}
}

@keyframes shiftLeft {
0% {
    left: -50%;
}
100% {
    left: -53%;
}
}

@keyframes shiftRight {
0% {
    right: -95%;
}
100% {
    right: -93%;
}
}
.lyrics{margin: 0;
            top: 22%;
            left: 50%;
    transform: translate(-50%, -50%);
            height: 100px; /**/
                 text-align: center;
            position: absolute;z-index: 1;
      }
            .lyric-line{
            width: 100%;
            position: relative;
            height: 60px;
            overflow: visible;
   font: 400 30px '仿宋', sans-serif;
            line-height: 60px;
         text-align: left;
            
            white-space: nowrap; /**/
            
      }

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

      .lyric-original {
             color: #800000;
            white-space: nowrap;
            
      }
#player {
        position: absolute;z-index: 40;
        left:5%;
        bottom: 260px;
        width: 100px;
        height: 40px;
         opacity: 1;
        transition: .4s;
display: grid;
        place-items: center;
        --sp1: 0; --sp2: 1;
}
#player::before, #player::after {
        position: absolute;
        content: '';
        cursor: pointer;
        transition: .4s;
}
#player::before {width: 100%;height: 100%;background:url(https://upfile.mp3.wf/view.php/bf412d5ea1e5d59bc588fe904de95be8.png)no-repeat center/cover;
        opacity: var(--sp1);}
#player::after {width: 100%;height: 100%;background:url(https://upfile.mp3.wf/view.php/4d803fbee0a975f8572b8cd36b541a93.png )no-repeat center/cover;
        opacity: var(--sp2);}
#tmsg {position: absolute;z-index: 1;
      font: normal 14px sans-serif;
      color: #eee;
         bottom: 35px;
      left:250px;}
#prog {position: absolute;z-index: 8;filter:invert(0%) hue-rotate(0deg);
      width: 444px;
      height: 6px;
      cursor: pointer;
         bottom: 252px;
left:11%;}
</style>
<div id="papa">

        <div class="k-container-body">
                <span class="k-screw top-left"></span>
                <span class="k-screw top-right"></span>
                <span class="k-screw bottom-left"></span>
                <span class="k-screw bottom-right"></span>
                <div class="k-centerreel">
                        <div class="reel left"></div>
                        <div class="center-tape"></div>
                        <div class="reel right"></div>
                </div>
                <div class="k-label"></div>
                <div class="k-chin">
                        <span class="holes"></span>
                        <span class="holes"></span>
                        <span class="holes"></span>
                        <span class="holes"></span>
                </div>

<div class="lyrics" >
            <div class="lyric-line">
                  <div class="lyric-mask"></div>
                  <div class="lyric-original"></div>
                </div>
            </div>
<div id="player" title="暂停/播放" ></div>
<div id="tmsg">00:00/00:00</div>
<progress id="prog"></progress>
</div>

</div>

<audio id="aud" src="https://aod.cos.tx.xmcdn.com/storages/5a0e-audiofreehighqps/99/12/GMCoOR4JYQAeACAAAAKSuus2.m4a" loop autoplay></audio>
<script>
const kcenterreel = document.querySelector('.k-centerreel');
const kcontainerbody= document.querySelector('.k-container-body');
player.onclick = () => aud.paused ? aud.play() : aud.pause();
        mState = () => papa.style.setProperty('--state',aud.paused ? (player.style.setProperty('--sp1','1' ), player.style.setProperty('--sp2','0'),'paused') : (player.style.setProperty('--sp1','0'), player.style.setProperty('--sp2','1'),'running'));

aud.onplaying = aud.onpause = () => mState();
aud.ontimeupdate = () => prog.value=aud.currentTime/aud.duration;
prog.onclick = (e) => aud.currentTime=aud.duration*e.offsetX/prog.offsetWidth;
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>
      // ksclrc
      const lrc = `听心 (经典版) - 魏佳艺
词:郭高见
曲:陈伟
编曲:李德奎
混音:潘君明
和声:夏初安
制作人:郜锦标
企划/统筹:吴聪聪
宣传推广:郜锦标/吴聪聪
艺人统筹:刘丹
OP:北京嘎嘎飙壹文化传媒有限公司
(此版本为正式授权翻唱作品)
闭上眼我想看见你
屏住了所有的呼吸
我怕你走错了轨迹
做了心跳的标记
在梦里总有个秘密
总是让我挥之不去
忍不住探索了心底
为何你摸索了离去
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近你一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
闭上眼我想看见你
屏住了所有的呼吸
我怕你走错了轨迹
做了心跳的标记
在梦里总有个秘密
总是让我挥之不去
忍不住探索了心底
为何你摸索了离去
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
让你能够听到我的心
什么时候也能把我想起
`;

      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>

小辣椒 发表于 2025-10-27 23:25

套了个亚纶的代码,改了微风的LOGO
页: [1]
查看完整版本: 听心 (经典版) - 魏佳艺