四季歌 发表于 2026-7-18 16:12:47

采蘑菇的小姑娘

<style>@import url("https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap");
    #bj {
      position: relative;
      width: 1400px;
      height: 720px;
      margin-left: -300px;
      margin-top: 10px;
      overflow: hidden;
      background:#000   url("https://picasa.eu.org/i/2026/07/18/gjz5rf.jpg")no-repeat;
background-size: cover;font-family: "Ma Shan Zheng","仿宋体","SimHei", "Arial", "sans-serif"
    }
#background{z-index: 1;
width: 100%; height: 100%;
    background: url("https://picasa.eu.org/i/2026/07/18/gjz0nv.jpg")no-repeat;
position: absolute;
    top: 0px;
    left: 0px;
animation: c 8s linear infinite;
background-size: cover;
}
@keyframes c {
    from{transform: scale(1) ;filter: hue-rotate(0deg);
    }
50%{transform: scale(4);
    }
   
100%{transform: scale(4);opacity: 0;
    }
}

.lyrics{margin: 0;z-index: 20;
            top: 69%;display: none;
            left: 50%;
    transform: translate(-50%, -50%);
            height: 100px; /* 调整高度,只容纳当前歌词 */
                 text-align: center;
             position: absolute;animation:sese 1s infinite alternate;
      }
            .lyric-line{
            width: 100%;
            position: relative;
            height: 60px;
            overflow: visible;
   font: 400 40px "Ma Shan Zheng","仿宋体","SimHei", "Arial", "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: #ff0000;
            height: 100%;
            white-space: nowrap;
      }

      .lyric-original {
             color: #00aa00;
            white-space: nowrap;
            
      }   
      
#wrapper {z-index: 9;
                position: absolute; writing-mode: vertical-lr;white-space: pre; width: 60px;height: 90%;top: 50px; left: 88%;
                padding: 0px;
                font:normal 2.6em "Ma Shan Zheng","仿宋体","SimHei", "Arial", "sans-serif";
                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);
      
        }

        .char {
                display: inline-block;
                padding: 2px 2px;
                opacity: 0;
                transform: translate(var(--x), var(--y));
                animation: fadeIn 1.5s var(--delay) forwards, sese 1s infinite alternate;
        }
       
        @keyframes fadeIn {
                to {
                        transform:scale(1);
                        opacity: 1;
                }
        }
        @keyframes flash {
                to { filter: hue-rotate(360deg)brightness(100%); }
        }
.lrc { z-index: 21; position: absolute; top: 20%; left: 41%; width: 740px; height: 350px; overflow: hidden; opacity: 0;}
.lrc #ul { width: 100%; padding: 0; list-style: none; transition: 0.3s all ease; margin: 0; }
.lrc #ul li { color: #fff; font: 300 20px 'YouYuan', sans-serif; transition: .3s all ease; list-style-type: none; text-align: center; display: block; padding: 0 10px; height: 50px; line-height: 50px; margin: 0 auto; cursor: pointer; }
.lrc #ul li.active { transform: scale(1.2); color: #FF0000; font-weight: 650; }
#s,#dh, #d, #g,#fullscreen{border-radius: 4px;position: relative;
color:#fff;background:#0000;box-shadow:0px 0px 0px 1px #fff;
padding: 4px 8px;z-index: 120;
font-size: 12px;
border: none;
cursor: pointer;top: 50px;left: 3%;
}

#bfq{   
      position:absolute;
      width: 350px;
      height:350px;overflow: hidden;
      background: url('https://pic1.imgdb.cn/item/69ae5a3fafde4f1fb1c6982e.png') no-repeat center/100%;
transform:scale(.28);top: 66%; box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 8px #000;
   left: -120px;z-index: 20;}
#cp{   
      position:absolute;
      width: 245px;border-radius: 50%;
      height:245px;animation: rotating 6s infinite linear;
      top:19%;background:repeating-radial-gradient(black, black 5px, #1C1C1C 6px, #1C1C1C 7px);
   cursor: pointer;
   left: 11%;z-index: 1;box-shadow:0px 0px 0px 1px #fff,0px 0px 0px 0px #880000;}
@keyframes rotating { to { transform: rotate(360deg); } }
.overlay {
content: '';
left: 50%;
top: 50%; transform: translate(-50%, -50%);
position: absolute;
width: 238px;
height: 238px;
background: linear-gradient(45deg, transparent, 40%, rgba(255,255,255,0.25), 60%, transparent);
border-radius: 50%;
}


.inner {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
box-shadow:0px 0px 0px 1px #eee,0px 0px 0px 2px #444;
background:#880000 url('') no-repeat center / cover;

border-radius: 50%;
}
.inner::before {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 15px;
height: 15px;
background: #ccc;
border-radius: 50%;
}
#cz {position: absolute;
      top:-3%; left:50%;z-index: 2;
      width: 150px;background: url('https://pic1.imgdb.cn/item/6688e0dad9c307b7e9a7a3e1.png')no-repeat center/85%;
      height: 300px;
      cursor: pointer;
}

.pink { transform:rotate(0deg);transform-origin: 100% 0%;}
.purple {transform-origin: 80% 0%;margin: 0px -25px;transform:rotate(-20deg);}

#biao{
    position:absolute;background:#800000 url('https://pic1.imgdb.cn/item/69ac017f3dbab1ba32d7193b.png') no-repeat center/100% 100%;width:620px;height: 350px;border-radius:2%;transform:scale(0.2);
top: 62%; left: 25%;box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 8px #000;
animation:sese 6sinfinite alternate;z-index: 20;
}
#zhen{position: absolute; transform: translate(-50%, -50%);
    background:#ff0000;width:4px;height: 185px;border-radius:0% 0% 50% 50%;
transform-origin:center 0%;top: 270px; left: 50%;
animation:swin 0.4s ease-in-out infinite alternate;
}
#zhe{position: absolute; transform: translate(-50%, -50%);
    background:#ff0000;width:4px;height: 185px;display: none;border-radius:0% 0% 50% 50%;
transform-origin:center 0%;top: 270px; left: 50%;
animation:swsw 1s ease-in-out infinite alternate;
}
#dian { width: 20px;height: 20px; background: #fff;top: 270px; left: 50%;position: absolute;
border-radius:50%;transform: translate(-50%, -50%);
}
@keyframes swin{
100%{
    transform:rotate(-180deg);
}
    60%{
    transform:rotate(-160deg);
}
40%{
    transform:rotate(-170deg);
}

0%{
    transform:rotate(-140deg);
}
}
@keyframes swsw{
0%{
    transform:rotate(-235deg);
}
100%{
    transform:rotate(-235deg);
}
}
@keyframes sese{
0%{filter:hue-rotate(360deg)contrast(110%)brightness(90%);
   
}

}
#ba{
    position: absolute;background: url('https://pic1.imgdb.cn/item/69ae5f7dafde4f1fb1c698f3.png') no-repeat center/100%;width:200px;height: 200px;border-radius:2%;transform:scale(0.5);box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 4px #000;
top: 77%; right: -4%;z-index: 20;

}
#laba{position: absolute; transform: translatex(-50%);
    background:url('https://pic1.imgdb.cn/item/69abf5b03dbab1ba32d6bd4d.png') no-repeat 0px 0px/100% 100%;width:150px;height: 150px;
top: 26px; left: 23px;text-align: center;cursor: pointer;
animation:sin 0.6sinfinite alternate;
}

@keyframes sin{
100%{
    transform:scale(1);
}
    40%{
    transform:scale(1.02);
}


0%{
    transform:scale(1);
}
}
#playbtn{margin: 0 120px ;top: 94.5%;width: 30px; height: 30px;position: absolute;cursor: pointer; z-index: 90;}
#cndpt{position: absolute; width: 80%; height:80%;
background:#fff;
clip-path: polygon(0% 0%, 0% 100%, 25% 100%, 25% 0, 50% 0, 50% 100%, 75% 100%, 75% 0);}
#enopg{ position: absolute;width: 80%; height: 80%;
opacity:0; background:#fff;
   clip-path: polygon(75% 50%, 0 0, 0 100%)
}

#prog {position:absolute;
      width: 68%;
      height: 6px;background:#fff;
      cursor: pointer;
         bottom: 3%;border-radius: 2px;
left:13%;z-index: 190;}
#prog-bar {border-radius: 2px;
            height: 100%;
            background: #880000;
            width: 0%;
      }

#tmsg {position:absolute;
      font: 600 14px sans-serif;
      color: #fff;
         bottom: 2%;
      right: 10%;z-index: 90;}
</style>

<div id="bj">
<div class="s" id="background"></div>
<div id="bfq">
<div id="cz"class="pink"></div>
<div id="cp"><div class="inner"></div> <div class="overlay"></div></div>
</div>
<div id="biao">
<div id="zhen"></div>
<div id="zhe"></div>
<div id="dian"></div>
</div>
<div id="ba">
<div id="laba"></div>
</div>
<div id="wrapper">采蘑菇的小姑娘</div>

    <div class="lyrics" >
            <div class="lyric-line">
                  <div class="lyric-mask"></div>
                  <div class="lyric-original"></div>
                </div>
            </div>
<div class="lrc">
            <ul id="ul"></ul>
      </div>
<div>
<span id="g" title="横/竖歌词模式">横排歌词</span>
<span id="d" onclick="btn()" title="多行歌词模式">多行歌词</span>
<span id="dh" onclick="btndh()" title="动画">动画变色</span>
<span id="s" onclick="btns()" title="动画">动画复原</span>
<span id="fullscreen" title="屏展模式">全屏欣赏</span>
</div>

<div id="playbtn"   title="暂停">
<div id="cndpt"title="暂停"></div>
<div id="enopg" title="播放"></div>
</div>
<div id="prog" title="播放进度条"><div id="prog-bar"></div></div>
<div id="tmsg"></div>
</div>
<audio id="aud" src="https://up.mediy.cn/%E9%87%87%E8%98%91%E8%8F%87%E7%9A%84%E5%B0%8F%E5%A7%91%E5%A8%98_92a5dbdb1b15f1bf9d2e9a2dfee9b63e.mp3" loop autoplay></audio>
<script>
    const lrc = `陈晓光作词,
谷建芬作曲,
朱逢博首唱
采蘑菇的小姑娘
背著一個大竹筐
清早光著小腳丫
走遍樹林和山崗
她采的蘑菇最多
多得像那星星數不清
她采的蘑菇最大
大得像那小傘裝滿筐
噻籮籮哩噻籮籮哩噻
噻籮籮哩噻籮籮哩噻
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮噻籮籮籮哩噻
誰不知山里的蘑菇香
她卻不肯嘗一嘗
攢到趕集的那一天
快快背到集市上
換上一把小鐮刀
再加上幾塊棒棒糖
和那小伙伴一起
把勞動的幸福來分享
噻籮籮哩噻籮籮哩噻
噻籮籮哩噻籮籮哩噻
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮籮籮籮哩噻
`;

   const aud= document.getElementById('aud');
      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 = '300';
            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);



const gcAr = lrc2HC(lrc);
        let curkey = 0, isSeeking = false;

        aud.ontimeupdate = () => {
                if(curkey > gcAr.length - 1) return;
                if(aud.currentTime >= gcAr) {
                        const gap = gcAr?. ?? 0 - gcAr;
                        showLrc(gcAr, wrapper, gap);
                }
        };

        aud.onended = () => {
                curkey = 0;
                aud.play();
        }

        aud.onseeked = () => calcKey();

        function lrc2HC(text) {
                let lrcAr = [];
                let ar = text.trim().split('\n');
                ar.sort();
                let reg = /\[(\d+)[.:](\d+)[.:](\d+)\](.*)/;
                ar.forEach(item => {
                        if(reg.test(item)) {
                                let result = item.match(reg);
                                let tmsg = parseInt(result) * 60 + parseInt(result) + parseInt(result) / 1000;
                                lrcAr.push(.trim()]);
                        }
                });
                return lrcAr ? lrcAr : ;
        };

        function calcKey() {
                for (let j = 0; j < gcAr.length; j++) {
                        if (aud.currentTime <= gcAr) {
                                curkey = j - 1;
                                break;
                        }
                }
                if (curkey < 0) curkey = 0;
                if (curkey > gcAr.length - 1) curkey = gcAr.length - 1;
                let time = gcAr?. ?? 0 - gcAr;
                isSeeking = false;
                showLrc(gcAr, wrapper, time);
        }

        function showLrc(str, targetElm, time) {
                if(isSeeking) return;
                targetElm.innerHTML = '';
                const chars = str.split('').map(c => c === ' ' ? ' ' : c);
                const frg = document.createDocumentFragment();
                chars.forEach((char, idx) => {
                        const span = document.createElement('span');
                        span.innerHTML = char;
                        span.classList.add('char');
                        const x = Math.random() * (Math.random() > 0.5 ? 600 : -300);
                        const y = Math.random() * (Math.random() > 0.5 ? 600 : -300);
                        span.style.cssText += `
                                color: #${Math.random().toString(16).substring(2,8)};
                                --x: ${x}px;
                                --y: ${y}px;
                                --delay: ${Math.random() * 0.5}s;
                        `;
                        frg.appendChild(span);
                });
                targetElm.appendChild(frg);
                curkey ++;
                setTimeout(() =>isSeeking = false, time);
        }
</script>
<script>
let lrcArr = lrc.split('\n');
      let result = [];
      var audio = document.querySelector("#aud");
      var ul = document.querySelector("#ul");
      var container = document.querySelector(".lrc");

      for (let i = 0; i < lrcArr.length; i++) {
            var lrcData = lrcArr.split(']');
            if (lrcData.length < 2) continue;
            var lrcTime = lrcData.substring(1);
            var obj = {
                time: parseTime(lrcTime),
                word: lrcData.trim()
            }
            result.push(obj);
      }

      function parseTime(lrcTime) {
            let lrcTimeArr = lrcTime.split(":");
            return +lrcTimeArr * 60 + parseFloat(lrcTimeArr);
      }

      function getIndex() {
            let time = audio.currentTime;
            for (let i = 0; i < result.length; i++) {
                if (result.time > time) {
                  return i - 1;
                }
            }
            return result.length - 1;
      }

      function createElements() {
            let fragment = document.createDocumentFragment();

            for (let i = 0; i < result.length; i++) {
                let li = document.createElement("li");
                li.innerText = result.word;

                li.addEventListener("click", function () {
                  audio.currentTime = result.time;
                  setOffset();
                });

                fragment.appendChild(li);
            }

            ul.appendChild(fragment);
      }

      createElements();
      let containerHeight = container.clientHeight;
      let liHeight = ul.children?.clientHeight || 50;
      let minOffset = 0;
      let maxOffset = ul.clientHeight - containerHeight;

      function setOffset() {
            const index = getIndex();
            if (index < 0) return;

            const liHeight = ul.children?.clientHeight || 50;
            let offset = liHeight * index - containerHeight / 2 + liHeight / 2;

            offset = Math.max(minOffset, Math.min(offset, maxOffset));

            ul.style.transform = `translateY(${-offset}px)`;

            ul.querySelectorAll('.active').forEach(li => li.classList.remove('active'));
            if (index < ul.children.length) {
                ul.children.classList.add('active');
            }
      }

      audio.addEventListener("timeupdate", setOffset);

</script>


<script>
   
var g1=document.getElementById("wrapper");
var dh=document.getElementById("background");
const g2 = document.querySelector('.lyrics');
const d = document.querySelector('.lrc');
const s = document.querySelector('.s');
functionbtn(){
            d.style.opacity= '1';

            g1.style.display = 'none';
            g2.style.display = 'none';
      };



   
            
          functionbtndh(){
            dh.style.filter= 'hue-rotate(360deg)';
dh.style.animation= 'c 6s linear infinite';
};
functionbtns(){
            s.style.filter= 'hue-rotate(0deg)';
s.style.animation= 'c 6s linear infinite';
};



let fss = true;
      g.onclick = () => {
            if (fss) {g.innerText = '竖排歌词';
               g1.style.display = 'none';
            g2.style.display = 'block';
d.style.opacity= '0';
            }else {g.innerText = '横排歌词';
               g1.style.display = 'block';
            g2.style.display = 'none';
d.style.opacity= '0';
            }
            fss = !fss;
      };


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

prog.onclick = (e) => { aud.currentTime = aud.duration * e.offsetX / prog.offsetWidth;}
var progBar = document.getElementById('prog-bar');
aud.addEventListener('timeupdate', () => {
          varpercent= (aud.currentTime / aud.duration) * 100;
            progBar.style.width = percent + '%';
      });
          aud.addEventListener('timeupdate', () => {
                tmsg.innerText = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);});


let toMin = (val) => {
                if (!val) return '00:00';
                val = Math.floor(val);
                let min = parseInt(val / 60),
                        sec = parseFloat(val % 60);
                if (min < 10) min = '0' + min;
                if (sec < 10) sec = '0' + sec;
                return min + ':' + sec;
      };   
               
playbtn.onclick=() => aud.paused ? (aud.play(),enopg.style.opacity= '0',cndpt.style.opacity = '1',background.style.animationPlayState = 'running', cz.classList.remove('purple'),intro.style.animationPlayState = 'running') : (aud.pause(),enopg.style.opacity = '1',cndpt.style.opacity = '0',background.style.animationPlayState = 'paused',cz.classList.add('purple'),intro.style.animationPlayState = 'paused');
playbtn.style.animationPlayState = aud.paused ? 'paused': 'running';
let mState = () => aud.paused ? (zhen.style.display= 'none',zhe.style.display= 'block') : (zhen.style.display= 'block',zhe.style.display= 'none');
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());
const intro= document.querySelector('.intro');
laba.style.animationPlayState=cp.style.animationPlayState =aud.paused ? 'paused' : 'running';
aud.addEventListener('playing', () =>laba.style.animationPlayState=cp.style.animationPlayState= 'running');
aud.addEventListener('pause', () =>laba.style.animationPlayState=cp.style.animationPlayState= 'paused');
      
</script>
页: [1]
查看完整版本: 采蘑菇的小姑娘