难忘今宵
<!DOCTYPE html><html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>难忘今宵</title>
</head>
<body>
<style>
@import url("https://fonts.googleapis.cn/css2?family=Ma+Shan+Zheng&display=swap");
.stage{margin: 130px 0 20px calc(50% - 781px);width: 1400px;height: 780px;background: #000;box-shadow: 3px 3px 6px gray;z-index: 1;overflow: hidden;user-select: none;position: relative;--state: running;border-radius: 32px;}
.heroes-show{position: absolute;top: 145px;left: 0;width: 100%;display: flex;align-items: center;justify-content: space-around;flex-wrap: nowrap;z-index: 8;transform: perspective(1em) rotateX(1deg);transform-origin:center;}
.worker-card{width: 160px;height: 160px;background: transparent;opacity: 0;cursor: pointer;animation: gentleBreathing 16s ease-in-out infinite,flash 1s infinite alternate,rotating 6s infinite linear;}
.worker-card img{width: 100%;height: 100%;object-fit: contain;display: block;backdrop-filter:lighten;}
.worker-card:nth-child(1){animation-delay: 0s;}
.worker-card:nth-child(2){animation-delay: 2s;}
.worker-card:nth-child(3){animation-delay: 4s;}
.worker-card:nth-child(4){animation-delay: 6s;}
@keyframes gentleBreathing {0%{opacity: 0;}15%{opacity: 1;}85%{opacity: 1;}100%{opacity: 0;}}
@keyframes flash {to{filter: hue-rotate(360deg);}}
@keyframes rotating{0%{transform:rotate(-90deg);}25%{transform:rotate(0deg);}50%{transform:rotate(90deg);}75%{transform:rotate(0deg);}100%{transform:rotate(-90deg);}}
.bg-video{position: absolute;top: 0;left: 0;width: 100%;height: 100%;object-fit: fill;pointer-events: none;z-index: 3;mask: linear-gradient(to right top, red 70%, transparent 90%);-webkit-mask: linear-gradient(to right top, red 70%, transparent 90%);}
.bg-video:nth-child(2){top: -10%;left: -10%;width: 120%;height: 120%;opacity: 0.6;mix-blend-mode: screen;mask: linear-gradient(to bottom, red 20%, transparent 60%);-webkit-mask: linear-gradient(to bottom, red 20%, transparent 60%);}
.song-info-vertical, .song-info-vertical2, .song-info-vertical3, .song-info-vertical4{position: absolute;writing-mode: vertical-rl;text-orientation: mixed;font-size: 1rem;font-weight: bold;font-family: YouYuan, '华文琥珀', 'Segoe UI', cursive;color: transparent;letter-spacing: 6px;z-index: 8;pointer-events: none;filter: drop-shadow(0 0 8px rgba(255,200,0,0.7));white-space: nowrap;}
.song-info-vertical{left:46.03%;top: 43%;transform: perspective(1em) rotateY(6deg);}
.song-info-vertical2{left: 44.03%;top: 43%;transform: perspective(1em) rotateY(-6deg);}
.song-info-vertical3{left: 91.2%;top: 57%;transform: perspective(1em) rotateY(6deg);}
.song-info-vertical4{left: 89.2%;top: 57%;transform: perspective(1em) rotateY(-6deg);}
.song-info-vertical::before, .song-info-vertical2::before,.song-info-vertical3::before, .song-info-vertical4::before{position: absolute;content: attr(data-text);top: 0;left: 0;width: 100%;height: 0%;color: #FFD966;background: linear-gradient(to bottom, #FFBF00, #FF7F00, #FFD966);background-clip: text;-webkit-background-clip: text;overflow: hidden;white-space: nowrap;filter: drop-shadow(0 0 5px #ffaa44);animation: textFillVertical 5.2s infinite alternate ease-in-out;text-shadow: 0 0 2px darkorange;writing-mode: vertical-rl;text-orientation: mixed;}
.song-info-vertical3::before, .song-info-vertical4::before{color: #98FB98;filter: drop-shadow(0 0 5px #7CFC00);}
.song-info-vertical.pause-animation::before,.song-info-vertical2.pause-animation::before,.song-info-vertical3.pause-animation::before,.song-info-vertical4.pause-animation::before{animation-play-state: paused !important;}
@keyframes textFillVertical {0%{height: 0%;letter-spacing: 8px;opacity: 0.7;}40%{letter-spacing: 2px;}100%{height: 100%;letter-spacing: 1px;opacity: 1;}}
#lrc{position: absolute;left: 0;right: 0;bottom: 25px;text-align: center;z-index: 8;font: normal 2.5rem STSong,'华文琥珀', 'Segoe UI', cursive;filter: drop-shadow(0 4px 12px rgba(0,0,0,0.6)) drop-shadow(0 0 6px #ffcc55);letter-spacing: 3px;pointer-events: none;display: flex;flex-wrap: wrap;justify-content: center;align-items: baseline;padding: 0 20px;transform: perspective(2em) rotateX(18deg);transform-origin: bottom center;}
.lrc-char{display: inline-block;color: #FFE484;font-size: 1.2em;font-weight: bold;text-shadow: 0 0 8px #ff9900, 2px 2px 5px #000;transform-origin: center center;margin: 0 2px;}
.lrc-space{display: inline-block;width: 0.56em;}
.lrc-char.spin{animation: spinOnce 2s cubic-bezier(0.4, 0.4, 0.4, 0.4) forwards;}
@keyframes spinOnce {0%{transform: rotate(0deg) scale(1);filter: brightness(1);color: #fff6c0;}50%{transform: rotate(180deg) scale(1.15);filter: brightness(2);color: #fff9c8;}100%{transform: rotate(360deg) scale(1);filter: brightness(1);color: #FFE484;}}
.independent-progress{position: absolute;top: 12%;left:calc(50% - 20px);transform:translateX(-50%);background: transparent;backdrop-filter: none;padding: 6px 15px;border-radius: 40px;display: flex;justify-content:space-between;align-items: center;z-index: 10;}
.independent-progress input{display: flex;justify-content:space-between;align-items:center;width: 180px;height: 3px;-webkit-appearance: none;background:#ffecb3;border-radius: 4px;outline: none;cursor: pointer;}
.independent-progress input::-webkit-slider-thumb{-webkit-appearance: none;width: 10px;height: 10px;background: Lime;border-radius: 50%;cursor: pointer;box-shadow: 0 0 5px gold;}
.time-indicator,#buttonTime{font-family: monospace;font-size: 15px;color: #ffecb3;background: transparent;padding: 2px 8px;border-radius: 20px;}
#bgCanvas {position: absolute;left: 31%;top: 51%;display: flex; align-items: center;justify-content: center; width: 50%;height: 50%;object-fit: cover;z-index: 6;pointer-events: none;opacity: 0.8;}
.dancer {mix-blend-mode: screen;mask: radial-gradient(circle at center, black 30%,transparent 50%,);-webkit-mask: radial-gradient(circle at center, black 30%,transparent 50% );}
.playback-btn{position: absolute;top: 67.5%;left:51.5%;width:5%;height: 5%;cursor: pointer;z-index: 15;filter: drop-shadow(0 5px 12px rgba(0,0,0,0.4));transition: transform 0.2s ease;transform: perspective(2em) rotateX(18deg);transform-origin: bottom center;},
.playback-btn:hover{transform: perspective(2em) rotateX(18deg) scale(1.05);}
.playback-btn:active{transform: perspective(2em) rotateX(18deg) scale(0.96);}
@keyframes discRotate {0%{transform: rotate(0deg);}100%{transform: rotate(360deg);}}
.spin-group{animation: discRotate 4s linear infinite;transform-origin: 50px 50px;}
#h4{position: absolute;top: 5%;left: 50%;transform: translateX(-50%);padding: 5px;letter-spacing: 20px;font-weight: 600;font-size: 3.8em;font-family:"Ma Shan Zheng",STXingkai, "华文行楷",STSong,'华文琥珀', 'Segoe UI', cursive;z-index: 10;}
#h4 span{position: relative;animation: my-words 1.5s infinite var(--state);}
#h4 span:nth-child(1){animation-delay: 0.2s;color: #6495ED;text-shadow: 0 0 1px #6495ED, 0 0 3px #87CEFA;}
#h4 span:nth-child(2){animation-delay: 0.4s;color: #98FB98;text-shadow: 0 0 1px #98FB98, 0 0 3px #B4EEB4;}
#h4 span:nth-child(3){animation-delay: 0.25s;color: #FF6B81;text-shadow: 0 0 1px #FF6B81, 0 0 3px #FF9AAA;}
#h4 span:nth-child(4){animation-delay: 0.35s;color: #FFD700;text-shadow: 0 0 1px #FFD700, 0 0 3px #FFEC8B;}
@keyframes my-words {0%{top: 0;}50%{top: -15px;}100%{top: 0;}}
#fullscreen{position:absolute;top:30px;right:30px;font:normal 1.5em 楷体;color:#fff;text-shadow:0 0 3px #000;opacity:1;cursor:pointer;user-select:none;z-index:8;}
#fullscreen:hover{font-style:italic;}
</style>
<div class="stage">
<video class="bg-video" muted playsinline autoplay loop>
<source src="https://img.tukuppt.com/video_show/3657157/00/02/08/5b504416e276b.mp4" type="video/mp4">
</video>
<video class="bg-video" muted playsinline autoplay loop>
<source src="https://img.tukuppt.com/video_show/15653652/01/59/07/63806a6eb7241.mp4" type="video/mp4">
</video>
<div id="h4"><span>难</span><span>忘</span><span>今</span><span>宵</span></div>
<div class="heroes-show">
<div class="worker-card"><img src="https://pic1.imgdb.cn/item/69874ced07b0859037cea432.png" alt="春" draggable="false"></div>
<div class="worker-card"><img src="https://s3.bmp.ovh/imgs/2025/12/18/8267fead3dbb8e27.png" alt="夏" draggable="false"></div>
<div class="worker-card"><img src="https://pic.imgdb.cn/item/67205f9dd29ded1a8cdba766.png" alt="秋" draggable="false"></div>
<div class="worker-card"><img src="https://s3.bmp.ovh/imgs/2025/12/18/7338334170436de4.png" alt="冬" draggable="false"></div>
</div>
<div class="song-info-vertical" data-text="无论天涯与海角神州万里同怀抱">无论天涯与海角神州万里同怀抱</div>
<div class="song-info-vertical2" data-text="无论天涯与海角神州万里同怀抱">无论天涯与海角神州万里同怀抱</div>
<div class="song-info-vertical3" data-text="青山在人未老共祝愿祖国好">青山在人未老共祝愿祖国好</div>
<div class="song-info-vertical4" data-text="青山在人未老共祝愿祖国好">青山在人未老共祝愿祖国好</div>
<div id="lrc" data-lrc="难忘今宵">难忘今宵</div>
<span id="fullscreen">全屏欣赏</span>
<div class="independent-progress">
<span id="buttonTime" class="time-indicator"> - 00:00</span>
<input type="range" id="progress" min="0" max="100" value="0" step="any" title="调节进度">
<span id="timeDisplay" class="time-indicator">00:00 | 00:00</span>
</div>
<canvas id="bgCanvas" class="dancer"></canvas>
<div class="playback-btn" id="playBtn">
<svg viewBox="0 0 100 100" style="display:block;">
<defs>
<radialGradient id="bgGrad" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#FFE89A"/>
<stop offset="70%" stop-color="#FFB347"/>
<stop offset="100%" stop-color="#CC7A00"/>
</radialGradient>
<radialGradient id="innerGrad" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#FFF7CC"/>
<stop offset="100%" stop-color="#FFD966"/>
</radialGradient>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="3" stdDeviation="3" flood-color="#000000" flood-opacity="0.5"/>
</filter>
</defs>
<circle cx="50" cy="50" r="45" fill="url(#bgGrad)" stroke="#FFDD99" stroke-width="2" filter="url(#shadow)"/>
<circle cx="50" cy="50" r="42" fill="none" stroke="#E6A817" stroke-width="1.5" stroke-dasharray="8 6"/>
<g id="rotatingGroup">
<circle cx="50" cy="50" r="30" fill="url(#innerGrad)" stroke="#FFAA33" stroke-width="1.5"/>
<text x="50" y="51" text-anchor="middle" dominant-baseline="central" font-size="28" font-weight="900" fill="#D32F2F" stroke="#8B0000" stroke-width="1.2" font-family="Arial, sans-serif">开心</text>
</g>
</svg>
</div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=395334.mp3" preload="auto" loop autoplay></audio>
</div>
<script>
(function(){
const audio = document.getElementById('aud');
const stage = document.querySelector('.stage');
const playbackBtn = document.querySelector('.playback-btn');
const bgVideo = document.querySelectorAll('.bg-video');
const progressBar = document.getElementById('progress');
const timeDisplaySpan = document.getElementById('timeDisplay');
const playBtn = document.getElementById('playBtn');
const buttonTime = document.getElementById('buttonTime');
const rotatingGroup = document.getElementById('rotatingGroup');
const songInfo1 = document.querySelector('.song-info-vertical');
const songInfo2 = document.querySelector('.song-info-vertical2');
const songInfo3 = document.querySelector('.song-info-vertical3');
const songInfo4 = document.querySelector('.song-info-vertical4');
const h4 = document.getElementById('h4');
const workers = document.querySelectorAll('.worker-card');
function collectAnimatedElements() {
const lrcChars = document.querySelectorAll('#lrc .lrc-char');
const elements = [...workers, ...lrcChars];
if (rotatingGroup) elements.push(rotatingGroup);
return elements;
}
function pauseAllAnimations() {
collectAnimatedElements().forEach(el => {
el.style.animationPlayState = 'paused';
});
if (songInfo1) songInfo1.classList.add('pause-animation');
if (songInfo2) songInfo2.classList.add('pause-animation');
if (songInfo3) songInfo3.classList.add('pause-animation');
if (songInfo4) songInfo4.classList.add('pause-animation');
}
function resumeAllAnimations() {
collectAnimatedElements().forEach(el => {
el.style.animationPlayState = '';
});
if (songInfo1) songInfo1.classList.remove('pause-animation');
if (songInfo2) songInfo2.classList.remove('pause-animation');
if (songInfo3) songInfo3.classList.remove('pause-animation');
if (songInfo4) songInfo4.classList.remove('pause-animation');
}
function formatTime(seconds) {
if (isNaN(seconds)) return "00:00";
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
function updateProgressAndTime() {
if (audio.duration) {
progressBar.value = (audio.currentTime / audio.duration) * 100;
timeDisplaySpan.innerText = `${formatTime(audio.currentTime)} | ${formatTime(audio.duration)}`;
let difference = audio.duration - audio.currentTime;
document.getElementById('buttonTime').textContent =`- ${formatTime(difference)}`;
}
}
function setPlayingVisual(isPlaying) {
if (isPlaying) {
rotatingGroup.classList.add('spin-group');
} else {
rotatingGroup.classList.remove('spin-group');
}
}
function togglePlayPause() {
if (audio.paused) {
audio.play().catch(e => console.warn("播放失败:", e));
} else {
audio.pause();
}
}
playBtn.addEventListener('click', (e) => {
e.stopPropagation();
togglePlayPause();
});
workers.forEach(card => {
card.addEventListener('click', (e) => {
e.stopPropagation();
togglePlayPause();
});
});
progressBar.addEventListener('input', () => {
if (!audio.duration) return;
audio.currentTime = (progressBar.value / 100) * audio.duration;
updateProgressAndTime();
});
audio.addEventListener('play', () => {
setPlayingVisual(true);
h4.style.setProperty('--state', 'running');
bgVideo.forEach(vid => vid.play().catch(e => console.warn("视频播放失败:", e)));
resumeAllAnimations();
workers.forEach(card => card.title = "暂停");
playBtn.title = "暂停";
});
audio.addEventListener('pause', () => {
setPlayingVisual(false);
h4.style.setProperty('--state', 'paused');
bgVideo.forEach(vid => vid.pause());
pauseAllAnimations();
workers.forEach(card => card.title = "播放");
playBtn.title = "播放";
});
audio.addEventListener('timeupdate', () => {
updateProgressAndTime();
updateLrcIndex();
});
audio.addEventListener('loadedmetadata', () => {
updateProgressAndTime();
setPlayingVisual(!audio.paused);
});
audio.addEventListener('ended', () => {
audio.currentTime = 0;
audio.play().catch(console.warn);
});
let mKey = 0, lastActiveCount = 0, played = [], lrcAr = [];
const geci = `
难忘今宵
李谷一 - 难忘今宵
难忘今宵难忘今宵
无论天涯与海角
神州万里同怀抱
共祝愿祖国好祖国好
难忘今宵难忘今宵
无论天涯与海角
神州万里同怀抱
共祝愿祖国好祖国好
共祝愿祖国好
共祝愿祖国好
告别今宵告别今宵
无论新友与故交
明年春来再相邀
青山在人未老人未老
青山在人未老
青山在人未老
共祝愿祖国好
共祝愿祖国好
`;
function parseLrc(text) {
const arr = [];
const lines = text.split('\n');
for (const line of lines) {
const match = line.match(/\[(\d+):(\d+)\.(\d+)\]/);
if (match) {
const time = parseInt(match)*60 + parseInt(match) + parseInt(match)/100;
const lyric = line.replace(/\[.*?\]/, '').trim();
if (lyric) arr.push({ time, lyric });
}
}
arr.sort((a,b)=>a.time-b.time);
for (let i=0; i<arr.length-1; i++) {
arr.duration = arr.time - arr.time;
}
if(arr.length) arr.duration = 4;
return arr;
}
lrcAr = parseLrc(geci);
function renderLrc(text) {
const lrcDiv = document.getElementById('lrc');
lrcDiv.innerHTML = '';
let visCount = 0;
for(const ch of text) {
if(ch.trim() === '') {
const sp = document.createElement('span');
sp.className = 'lrc-space';
lrcDiv.appendChild(sp);
} else {
const span = document.createElement('span');
span.className = 'lrc-char';
span.textContent = ch;
lrcDiv.appendChild(span);
visCount++;
}
}
played = new Array(visCount).fill(false);
lastActiveCount = 0;
}
function spinChar(idx) {
const chars = document.querySelectorAll('#lrc .lrc-char');
if(idx >= chars.length || played) return;
const span = chars;
span.classList.remove('spin');
void span.offsetHeight;
span.classList.add('spin');
played = true;
}
function updateCharActivation() {
if(mKey < 0 || mKey >= lrcAr.length) return;
const chars = document.querySelectorAll('#lrc .lrc-char');
const total = chars.length;
if(total === 0) return;
const now = audio.currentTime;
const start = lrcAr.time;
const duration = lrcAr.duration || 2.8;
const progress = Math.max(0, Math.min(1, (now - start) / duration));
const active = Math.ceil(progress * total);
for(let i = lastActiveCount; i < active; i++) spinChar(i);
lastActiveCount = active;
}
function showLrc() {
renderLrc(lrcAr.lyric);
updateCharActivation();
}
function updateLrcIndex() {
const cur = audio.currentTime;
let newKey = 0;
for(let i=0; i<lrcAr.length; i++) {
if(cur >= lrcAr.time) newKey = i;
}
if(newKey !== mKey) {
mKey = newKey;
showLrc();
} else {
updateCharActivation();
}
}
audio.addEventListener('seeked', updateLrcIndex);
if(lrcAr.length) showLrc();
stage.oncontextmenu = e => e.preventDefault();
let fs = true;
const fullscreen = document.getElementById('fullscreen');
let fsTimer;
fullscreen.onclick = () => {
if(fs) {
fullscreen.innerText = '退出全屏';
stage.requestFullscreen();
} else {
fullscreen.innerText = '全屏欣赏';
document.exitFullscreen();
}
fs = !fs;
};
stage.addEventListener('mousemove', () => {
clearTimeout(fsTimer);
fullscreen.style.opacity = '1';
fsTimer = setTimeout(() => fullscreen.style.opacity = '0', 3000);
});
playBtn.onanimationiteration = () => {
playBtn.style.filter = `hue-rotate(${60 + Math.random() * 240}deg)`;
};
})();
const TOTAL_FRAMES = 29;
const FRAME_DURATION_MS = 100;
let frames = [];
let framesLoaded = false;
let animationId = null;
let isPlaying = true;
const canvas = document.getElementById('bgCanvas');
const ctx = canvas.getContext('2d');
const audio = document.getElementById('aud');
const playBtn = document.getElementById('playBtn');
function getFrameUrl(index) {
const list = [
"https://xlaj.cn/upfile/2026/05/06/frame/frame_00_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_01_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_02_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_03_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_04_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_05_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_06_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_07_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_08_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_09_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_10_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_11_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_12_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_13_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_14_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_15_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_16_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_17_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_18_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_19_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_20_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_21_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_22_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_23_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_24_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_25_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_26_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_27_delay-0.1s.gif",
"https://xlaj.cn/upfile/2026/05/06/frame/frame_28_delay-0.1s.gif"
];
return list;
}
function loadFrames() {
let loadedCount = 0;
for (let i = 0; i < TOTAL_FRAMES; i++) {
const img = new Image();
img.src = getFrameUrl(i);
frames.push(img);
img.onload = () => {
loadedCount++;
if (loadedCount === TOTAL_FRAMES) {
framesLoaded = true;
canvas.width = 1300;
canvas.height = 762;
drawFrame(0);
requestAnimationFrame(updateFrame);
}
};
}
}
function drawFrame(index) {
if (!framesLoaded || !frames) return;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(frames,0,0,canvas.width,canvas.height);
}
let frameIndex = 0;
function updateFrame() {
if (!framesLoaded) { requestAnimationFrame(updateFrame); return; }
if (isPlaying) {
drawFrame(frameIndex);
frameIndex = (frameIndex + 1) % TOTAL_FRAMES;
}
setTimeout(()=>{
requestAnimationFrame(updateFrame);
}, FRAME_DURATION_MS);
}
function pauseAnimation() { isPlaying = false; }
function resumeAnimation() { isPlaying = true; }
function syncAllAnimations() {
const paused = audio.paused;
paused ? pauseAnimation() : resumeAnimation();
}
playBtn.onclick = (e) => {
e.stopPropagation();
syncAllAnimations();
};
audio.onplay = () => {
resumeAnimation();
};
audio.onpause = () => {
pauseAnimation();
};
loadFrames();
</script>
</body>
</html>
代码来自了了子老师、小辣椒管理员分享作品,在此表示感谢{:4_190:} https://img1.oldkids.cn/upload/2021/12/01/blog_260844733_20211201053404192.gif 高难度音画作品,这么多元素融合在一起,厉害了!{:4_187:} 谢谢杨帆精彩音画分享!{:4_204:}{:4_199:} 感谢杨帆的精彩分享,祝您制作愉快~~{:4_204:}{:4_190:}
{:4_199:} 现在,这样的词曲作者和歌唱演员太难找了。 连回个帖都没有,已经用在你帖上了 欣赏杨帆好制作{:4_187:} 也曾年轻 发表于 2026-5-7 17:48
谢谢年轻老师鼓励,请多指导{:4_190:} 梦江南 发表于 2026-5-7 18:22
谢谢杨帆精彩音画分享!
谢谢江南老师鼓励,祝开心{:4_204:} 霜染枫丹 发表于 2026-5-7 19:34
感谢杨帆的精彩分享,祝您制作愉快~~
谢谢枫丹老师鼓励,祝开心{:4_187:} 马黑黑 发表于 2026-5-7 19:45
谢谢马老师鼓励,请多指导{:4_190:} 梦油 发表于 2026-5-7 19:57
现在,这样的词曲作者和歌唱演员太难找了。
是啊,祝梦兄欣赏愉快{:4_190:} 梦江南 发表于 2026-5-7 18:20
高难度音画作品,这么多元素融合在一起,厉害了!
鼓捣着玩呢,音频用的是你的呦,谢谢江南{:4_204:} 小辣椒 发表于 2026-5-7 21:36
连回给帖都没有,已经用在你帖上了
只顾着欣赏学习了,你的逐帧动画制作很漂亮,迟复为歉{:4_180:} 小辣椒 发表于 2026-5-7 21:37
欣赏杨帆好制作
谢谢小辣椒鼓励,请多指导{:4_187:} 好漂亮的制作,精彩纷呈。
欣赏杨帆好帖{:4_199:} 红影 发表于 2026-5-7 22:22
好漂亮的制作,精彩纷呈。
欣赏杨帆好帖
谢谢影子鼓励,请多指导{:4_204:}
页:
[1]
2