采蘑菇的小姑娘 - 帖送红影
本帖最后由 花甲走四方 于 2026-7-19 08:57 编辑 <br /><br /><style>#bj {
position: relative;
width: 1186px;
height: 680px;
margin-left: -300px;
margin-top: 70px;
overflow: hidden;
background:#000 url("https://picasa.eu.org/i/2026/07/18/gjz5rf.jpg") no-repeat;
background-size: cover;
font-family: "楷体","仿宋体","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 "楷体","仿宋体","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 "楷体","仿宋体","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_btn,#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_btn" 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>
<script>
document.addEventListener('DOMContentLoaded', function(){
const lrc =`
陈晓光作词,
谷建芬作曲,
朱逢博首唱
采蘑菇的小姑娘
背著一個大竹筐
清早光著小腳丫
走遍樹林和山崗
她采的蘑菇最多
多得像那星星數不清
她采的蘑菇最大
大得像那小傘裝滿筐
噻籮籮哩噻籮籮哩噻
噻籮籮哩噻籮籮哩噻
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮噻籮籮籮哩噻
誰不知山里的蘑菇香
她卻不肯嘗一嘗
攢到趕集的那一天
快快背到集市上
換上一把小鐮刀
再加上幾塊棒棒糖
和那小伙伴一起
把勞動的幸福來分享
噻籮籮哩噻籮籮哩噻
噻籮籮哩噻籮籮哩噻
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮
噻籮籮籮籮籮籮哩噻
`;
const aud= document.getElementById('aud');
const lyrics = parseLyrics(lrc);
const lyricMask = document.querySelector('.lyric-mask');
const lyricOriginal = document.querySelector('.lyric-original');
const wrapper = document.getElementById('wrapper');
const s_btn = document.getElementById("s_btn");
const background = document.getElementById("background");
const g = document.getElementById("g");
const dBtn = document.getElementById("d");
const dhBtn = document.getElementById("dh");
const fullscreen = document.getElementById("fullscreen");
const g2 = document.querySelector('.lyrics');
const d = document.querySelector('.lrc');
const playbtn = document.getElementById("playbtn");
const cndpt = document.getElementById("cndpt");
const enopg = document.getElementById("enopg");
const cz = document.getElementById("cz");
const zhen = document.getElementById("zhen");
const zhe = document.getElementById("zhe");
const laba = document.getElementById("laba");
const cp = document.getElementById("cp");
const prog = document.getElementById("prog");
const progBar = document.getElementById('prog-bar');
const tmsg = document.getElementById('tmsg');
const bj = document.getElementById("bj");
let currentIndex = -1;
let currentLyric = null;
// 解析歌词
function parseLyrics(lrcText) {
const lyrics = [];
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`;
}
// 竖排文字歌词逻辑
const gcAr = lrc2HC(lrc);
let curkey = 0, isSeeking = false;
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.length ? 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?. ?? gcAr + 5;
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 * 1000);
}
// 底部滚动列表歌词
let lrcArr = lrc.split('\n');
let result = [];
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 = aud.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 () {
aud.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');
}
}
// 统一音频时间更新(不再覆盖)
aud.addEventListener('timeupdate', () => {
const currentTimeMs = aud.currentTime * 1000;
// 逐字遮罩歌词
const index = getCurrentLyricIndex(lyrics, currentTimeMs);
if (index !== currentIndex) updateLyricDisplay(index);
updateLyricMask(currentTimeMs);
// 竖排文字
if(curkey <= gcAr.length - 1 && aud.currentTime >= gcAr) {
const gap = gcAr?. ?? gcAr + 5;
showLrc(gcAr, wrapper, gap);
}
// 底部列表滚动
setOffset();
// 进度条
var percent= (aud.currentTime / aud.duration) * 100;
progBar.style.width = percent + '%';
tmsg.innerText = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
});
// 音频播放结束
aud.onended = () => {
curkey = 0;
aud.play();
}
aud.onseeked = () => calcKey();
// 切换按钮函数
window.btn = function(){
d.style.opacity= '1';
wrapper.style.display = 'none';
g2.style.display = 'none';
};
window.btndh = function(){
background.style.filter= 'hue-rotate(360deg)';
background.style.animation= 'c 6s linear infinite';
};
window.btns = function(){
background.style.filter= 'hue-rotate(0deg)';
background.style.animation= 'c 6s linear infinite';
};
// 横竖歌词切换
let fss = true;
g.onclick = () => {
if (fss) {
g.innerText = '竖排歌词';
wrapper.style.display = 'none';
g2.style.display = 'block';
d.style.opacity= '0';
}else {
g.innerText = '横排歌词';
wrapper.style.display = 'block';
g2.style.display = 'none';
d.style.opacity= '0';
}
fss = !fss;
};
// 全屏
let fs = true;
fullscreen.onclick = () => {
if (fs) {
fullscreen.innerText = '退出全屏';
if(bj.requestFullscreen) bj.requestFullscreen();
} else {
fullscreen.innerText = '全屏欣赏';
if(document.exitFullscreen) document.exitFullscreen();
}
fs = !fs;
};
// 进度条点击
prog.onclick = (e) => { aud.currentTime = aud.duration * e.offsetX / prog.offsetWidth;}
// 时间格式化
let toMin = (val) => {
if (!val) return '00:00';
val = Math.floor(val);
let min = parseInt(val / 60),
sec = Math.floor(val % 60);
if (min < 10) min = '0' + min;
if (sec < 10) sec = '0' + sec;
return min + ':' + sec;
};
// 播放暂停按钮
playbtn.onclick=() => {
if(aud.paused){
aud.play();
enopg.style.opacity= '0';
cndpt.style.opacity = '1';
background.style.animationPlayState = 'running';
cz.classList.remove('purple');
}else{
aud.pause();
enopg.style.opacity = '1';
cndpt.style.opacity = '0';
background.style.animationPlayState = 'paused';
cz.classList.add('purple');
}
};
// 指针动画同步
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());
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';
});
// 初始化
updateLyricDisplay(0);
calcKey();
})
</script> 好听的歌曲送给红影,祝影子朋友天天快乐。
问好花甲走四方朋友。 哇,这个还是送我的呢,太开心了,多可爱的采蘑菇的小姑娘啊。 这歌词展示用竖排横排以及多行三种演示方式呢,还有动画变色等不同效果,这个制作真漂亮。
谢谢高老师,这个礼物太喜欢了! 帖子好像有点问题,回帖表情没法用呢,还有两个音箱的小图标点击无用,横排歌词时还好,竖排歌词时点击歌词会跳跃较多。但不管怎么说制作效果还是很不错的。 送我的帖子,带点小私心地亮起来:) 临摹的不错! 谢谢走四方老师精彩分享,祝影子收礼开心
页:
[1]