苍天求你赐我一束光
<!DOCTYPE html><html>
<head>
<meta charset="utf-8">
<meta name="referrer" content="never" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>苍天求你赐我一束光</title>
</head>
<body>
<style>
@import url("https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap");
#papa { margin: 100px 0 30px calc(50% - 780px); width: 1400px; height: 780px; background: url('https://pic.imgdb.cn/item/63df47ee4757feff33e4d063.jpg') no-repeat center/cover; background-blend-mode: color-burn; overflow: hidden; position: relative; --state:running; font-family: "Ma Shan Zheng","华文行楷","SimHei", "Arial", "sans-serif";z-index: 1; }
#spectrum-wrap { position: absolute; left: 50%; top: 80%; transform: translateX(-50%); width: 50%;height: 180px;mix-blend-mode: screen; object-fit: cover;z-index: 2;transition: all 0.2s;}
#vid1 { position: absolute; top: -10%; left: -10%; width: 120%; height: 120%; mix-blend-mode: lighten; opacity: 0.8; object-fit: cover; z-index: 1; mask: linear-gradient(to bottom, red 20%,transparent 60%,transparent); -webkit-mask: linear-gradient(to bottom, red 20%,transparent 60%,transparent); }
#vid2 { position: absolute; top: -10%; left: -10%; width: 120%; height: 120%; mix-blend-mode: lighten; opacity: 0.98; object-fit: cover; z-index: 2; mask: linear-gradient(to bottom, red 30%,transparent 60%,transparent); -webkit-mask: linear-gradient(to bottom, red 30%,transparent 60%,transparent); }
#lyric { position: absolute; left: calc(50% - 50px); top: 5%; transform: translateX(-50%); z-index: 12; display: flex; flex-direction: column; justify-content: center; height: 100px; width: 90%; text-align: center; 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); font-size: 3em; white-space: pre; }
#lyricDisplay { height: 100%; width: 100%; letter-spacing: 0px; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; padding: 0 1em; width: 100%; }
.lyrichar { display: inline-block; opacity: 0; animation: charAppear 0.5s forwards,hue-rotate 0.5s linear infinite var(--state); margin: 0 2px; }
@keyframes charAppear { to { opacity: 1; transform: translate(0%); } }
.chooseBtn { display: none; }
.choose-label { position: absolute; top: 30px; left: 30px; width: 50px; height: 50px; border: 2px solid #000; box-shadow: 0 0 0 6px #ccc; border-radius: 50%; background: #ccc; cursor: pointer; transition: all 0.3s; z-index: 15 !important; }
.choose-label:hover { scale:1.1; }
.choose-label::before { content: ''; position: absolute; left: 16px; top: 12px; width: 4px; height: 24px; border-width: 0 8px; border-style: solid; border-color: #000; }
.chooseBtn:checked + .choose-label { background: #000; border-color: #ccc; box-shadow: 0 0 0 6px #000; }
.chooseBtn:checked + .choose-label::before { left: 18px; top: 10px; width: 0; height: 0; border-width: 14px 22px; border-color: transparent transparent transparent #ccc; border-style: solid; }
.progress-wrap { position: absolute; left: 50%; top: 90%; transform: translateX(-50%); width: 50%; z-index: 10; }
.time-box { display: flex; justify-content: space-between; color: #FFD700; font-size: 20px; margin-bottom:6px; }
#mprog { width: 100%; height: 3px; accent-color:#FFA500; outline: none; cursor: pointer; margin:0px;background: #2a1a0a; }
#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:15; }
#fullscreen:hover { font-style:italic; }
#Kite {position: absolute; left: 80%; top:53%; offset-path: path("M0,100 Q50,0 100,100 T200,100 T300,100"); offset-distance: 0%; offset-rotate: auto -90deg; offset-anchor: center; cursor: pointer;animation: swim 12s infinite ease-in-out var(--state),hue-rotate 0.5s linear infinite var(--state); z-index: 10;}
@keyframes swim {0% { offset-distance: 0%; }50%{ offset-distance: 50%; }100% { offset-distance: 0%; }}
@keyframes hue-rotate { to { filter: hue-rotate(360deg); } }
#Kite:hover {--state:paused;}
.dancer { position: absolute; z-index:1;}
</style>
<div id="papa">
<img id="Kite" src="https://638183.freep.cn/638183/small/hdxk.png" style = "width:10%; height: 10%;" alt="" />
<video id="vid1" src="https://www.llz123.net/llz/llz/mulu/wo/tian.mp4" autoplay loop muted playsinline></video>
<video id="vid2" src="https://yw83yw.oss-cn-hangzhou.aliyuncs.com/lvzhou/flash/MP4/DH04.mp4" autoplay loop muted playsinline></video>
<img class="dancer" id= "puppy" src="https://pic1.imgdb.cn/item/683fe00058cb8da5c82b1978.gif" alt="" style="width: 100px; height: 172px;left: 5%; bottom: 5%;-webkit-mask-image: radial-gradient(black 60% ,transparent 70%);cursor: pointer;transform: rotateY(3.1416rad);z-index:10;" >
<img class="dancer" id="spectrum-wrap" src="https://pic1.imgdb.cn/item/67ce8a52066befcec6e25b80.gif" alt=""/>
<audio id="aud" src="http://cccimg.com/view.php/a9195c4d14315551de4632364b7a839d.mp3" autoplay loop></audio>
<div id="lyric">
<div id="lyricDisplay"></div>
</div>
<svg id="svg" width="100%" height="100%" viewBox="0 0 1600 900">
<defs>
<g id="svgShape" fill="white" stroke="snow" style="animation: hue-rotate 1.5s linear infinite var(--state)">
<image x="0" y="0" width="140" height="78" href="https://www.helloimg.com/i/2025/09/21/68cfe74b9896b.png" />
</g>
<path id="motionPath" d="M-100 100 C300 300, 500 500, 800 450 S1200 100, 1500 350 S1900 500, 2200 200" />
</defs>
</svg>
<input type="checkbox" id="chooseBtn" class="chooseBtn">
<label for="chooseBtn" class="choose-label"></label>
<span id="fullscreen">全屏欣赏</span>
<div class="progress-wrap">
<div class="time-box">
<span id="current">00:00</span>
<span id="duration">00:00</span>
</div>
<input id="mprog" type="range" min="0" max="100" step="any" value="0" title="调节进度">
</div>
</div>
<script>
if ('getContext' in document.createElement('canvas')) {
HTMLImageElement.prototype.play = function() {
if (this.storeCanvas) {
this.storeCanvas.remove();
this.storeCanvas = null;
}
this.style.opacity = '1';
};
HTMLImageElement.prototype.stop = function() {
if (this.storeCanvas) return;
const canvas = document.createElement('canvas');
const w = this.offsetWidth;
const h = this.offsetHeight;
canvas.width = w;
canvas.height = h;
const style = getComputedStyle(this);
canvas.style.cssText = `
position: absolute;
left: ${style.left};
top: ${style.top};
width: ${w}px;
height: ${h}px;
transform: ${style.transform};
z-index: ${style.zIndex};
border-radius: ${style.borderRadius};
-webkit-mask-image: ${style.webkitMaskImage};
mask-image: ${style.maskImage};
clip-path: ${style.clipPath};
object-fit: ${style.objectFit};
object-position: ${style.objectPosition};
mix-blend-mode: ${style.mixBlendMode};
pointer-events: none;
`;
try {
const ctx = canvas.getContext('2d');
const ratioImg = this.naturalWidth / this.naturalHeight;
const ratioBox = w / h;
let drawW, drawH, offsetX = 0, offsetY = 0;
if (ratioImg > ratioBox) {
drawH = h;
drawW = h * ratioImg;
offsetX = -(drawW - w) / 2;
} else {
drawW = w;
drawH = w / ratioImg;
offsetY = -(drawH - h) / 2;
}
ctx.drawImage(this, offsetX, offsetY, drawW, drawH);
} catch (e) {}
this.parentNode.insertBefore(canvas, this);
this.style.opacity = '0';
this.storeCanvas = canvas;
};
}
const papa = document.getElementById('papa');
const Kite = document.getElementById('Kite');
const dancers = document.querySelectorAll('.dancer');
const videos = document.querySelectorAll('video');
const chooseBtn = document.getElementById('chooseBtn');
const label = document.querySelector('.choose-label');
const svgs = document.querySelectorAll('svg');
const mprog = document.getElementById('mprog');
const currentEl = document.getElementById('current');
const durationEl = document.getElementById('duration');
const audio = document.getElementById('aud');
const lyricDisplay = document.getElementById('lyricDisplay');
let currentLyricIndex = -1;
let isUpdating = false;
const lrcText = `
苍天求你赐我一束光-烟嗓兄弟
作词:烟嗓兄弟
作曲:罗扎阿
苍天请你赐我一束光
让我破开眼前的迷惘
回头看半生的风霜
全是岁月赐我的狂
我怕来日还是空荡荡
辜负年少许下的期望
咽下这杯烈酒穿肠
劈开所有险阻迷航
今生誓言绝不会投降
我又何惧命运的阻挡
越是想要将我捆绑
越是激起胸中热浪
就算双鬓染白成了霜
或许我还是要去远航
既然不甘平庸退场
就让孤勇陪我闯荡
`;
function parseLrc(lrc) {
const lyrics = [];
const lines = lrc.trim().split('\n');
const lrcRegex = /\[(\d{2}):(\d{2})\.(\d{2})\](.*)/;
lines.forEach(line => {
const match = line.match(lrcRegex);
if (match) {
const minutes = parseInt(match);
const seconds = parseInt(match);
const ms = parseInt(match);
const totalSeconds = minutes * 60 + seconds + ms / 100;
const text = match.trim();
lyrics.push({ time: totalSeconds, text: text });
}
});
return lyrics;
}
const lyrics = parseLrc(lrcText);
function displayLyricCharByChar(text) {
lyricDisplay.innerHTML = '';
const chars = text.split('');
const colorList = ['#ff0000', '#00aa00', '#fd27d2'];
chars.forEach((char, i) => {
const span = document.createElement('span');
span.className = 'lyrichar';
span.style.color = colorList;
span.textContent = char === ' ' ? ' ' : char;
span.style.animationDelay = `${i * 0.08}s`;
if (/[,。!?,.!?]/.test(char)) {
span.style.animationDelay = `${i * 0.08 + 0.08}s`;
}
lyricDisplay.appendChild(span);
});
}
audio.addEventListener('timeupdate', () => {
if (isUpdating) return;
isUpdating = true;
setTimeout(() => isUpdating = false, 100);
const currentTime = audio.currentTime;
for (let i = 0; i < lyrics.length; i++) {
const currentLyricTime = lyrics.time;
const nextLyricTime = i < lyrics.length - 1 ? lyrics.time : Infinity;
if (currentTime >= currentLyricTime - 0.3 && currentTime < nextLyricTime + 0.3) {
if (currentLyricIndex !== i) {
currentLyricIndex = i;
displayLyricCharByChar(lyrics.text);
}
break;
}
}
});
function resetLyrics() {
currentLyricIndex = -1;
lyricDisplay.innerHTML = '';
}
audio.addEventListener('ended', resetLyrics);
function updateState() {
if (audio.paused) {
puppy.title = Kite.title = label.title = "播放";
} else {
puppy.title = Kite.title = label.title = "暂停";
}
papa.style.setProperty('--state', audio.paused ? 'paused' : 'running');
svgs.forEach(svg => aud.paused ? svg.pauseAnimations() : svg.unpauseAnimations()); if (!svgs)return;
dancers.forEach(dancer => audio.paused ? dancer.stop() : dancer.play());
videos.forEach((vid) => {audio.paused ? vid.pause() : vid.play()});
}
chooseBtn.addEventListener('click', function() {
if (audio.paused) {
audio.play().catch(()=>{});
} else {
audio.pause();
}
updateState();
});
audio.addEventListener('playing', updateState);
audio.addEventListener('pause', updateState);
puppy.onclick = Kite.onclick = ()=> chooseBtn.click();
var mseek = false;
let toMin = (val) => {
if (!val) return '00:00';
val = Math.floor(val);
let min = parseInt(val / 60);
let sec = val % 60;
if (min < 10) min = '0' + min;
if (sec < 10) sec = '0' + sec;
return min + ':' + sec;
};
audio.addEventListener('loadedmetadata', () => {
durationEl.textContent = toMin(audio.duration);
});
audio.addEventListener('timeupdate', () => {
if (!mseek) {
mprog.value = audio.currentTime / audio.duration * 100;
}
currentEl.textContent = toMin(audio.currentTime);
});
mprog.onmousedown = () => mseek = true;
mprog.onmouseup = () => mseek = false;
mprog.oninput = () => {
audio.currentTime = mprog.value / 100 * audio.duration;
};
const svgSetting= { svg: svg, lz: 2, dur: 18, gap: 380 } ;
const svgMotion = () => {
const svg = svgSetting.svg;
if (!svg) return;
const total = svgSetting.lz || 20;
const createSvgElement = (element, attributes) => {
const elm = document.createElementNS('http://www.w3.org/2000/svg', element);
attributes.forEach(item => elm.setAttribute(item,item));
return elm;
};
const fragment = document.createDocumentFragment();
Array.from({length: total}).forEach((_,key) => {
const color = '#' + Math.random().toString(16).substring(2,8);
const size = (Math.random() + 0.8).toFixed(2);
const dur = svgSetting.dur || 10;
const delay = (-10 * Math.random()).toFixed(2);
const gap = svgSetting.gap || 150;
const use = createSvgElement('use', [
['href', '#svgShape'],
['x', 0],
['y', (-Math.random() * 10) - 50],
['style', `--delay: ${delay}s; transform: scale(${size}); fill: ${color}; stroke: ${color};`]
]);
const motion = createSvgElement('animateMotion', [
['dur', Math.random() * dur + dur],
['begin', `${delay}s`],
['repeatCount', 'indefinite'],
['rotate', 'auto']
]);
const mpath = createSvgElement('mpath',[
['href', '#motionPath']
]);
motion.appendChild(mpath);
use.appendChild(motion);
fragment.appendChild(use);
});
svg.appendChild(fragment);
};
svgMotion();
['contextmenu', 'dragstart','selectstart'].forEach(type =>
document.getElementById('papa').addEventListener(type, e => e.preventDefault())
);
let fs = true,fsTimer,labelTimer;
fullscreen.onclick = () => {
const randomColor = '#' + Math.random().toString(16).slice(2,8).padEnd(6,'0');
fullscreen.style.color = randomColor;
fs ? (fullscreen.innerText = '退出全屏',papa.requestFullscreen()) : (fullscreen.innerText = '全屏欣赏', document.exitFullscreen());fs = !fs;
};
papa.addEventListener('mousemove', () => {
clearTimeout(fsTimer);
fullscreen.style.opacity = '1';
fsTimer = setTimeout(() => {
fullscreen.style.opacity = '0';
}, 3000);
});
papa.addEventListener('mousemove', () => {
clearTimeout(labelTimer);
label.style.opacity = '1';
labelTimer = setTimeout(() => {
label.style.opacity = '0';
}, 3000);
});
</script>
</body>
</html>
https://5b0988e595225.cdn.sohucs.com/images/20180922/a0358ef38edd469fa54e7a2c2fe3a5ab.gif 我的浏览器有问题?点“全屏欣赏”和“播放/暂停”开关都不起作用。进度条也不起作用,有没有LRC歌词,我没看到有。{:5_117:} 还是两个小播呢,频谱很漂亮,小飞机和海星的移动路径设计也不错。
欣赏杨帆好帖{:4_199:} 欣赏杨帆精彩的制作,杨帆现在代码进步不少 但是小辣椒还是建议,你加的素材一点要和背景相符,这个背景是云动,山坡自然景象和纸飞机完全不得,你可以直接用真实的飞机,反正路径在的,这个是我个人的想法,也是不一定正确,只是建议吧了 也曾年轻 发表于 2026-4-13 21:27
谢谢老师鼓励,祝开心{:4_190:} 本帖最后由 杨帆 于 2026-4-14 00:18 编辑
寒冬残荷 发表于 2026-4-13 21:35
我的浏览器有问题?点“全屏欣赏”和“播放/暂停”开关都不起作用。进度条也不起作用,有没有LRC歌词,我没 ...
有呢,我这里显示正常呀{:4_187:} 红影 发表于 2026-4-13 22:10
还是两个小播呢,频谱很漂亮,小飞机和海星的移动路径设计也不错。
欣赏杨帆好帖
谢谢影子鼓励,祝开心{:4_204:} 小辣椒 发表于 2026-4-13 22:28
欣赏杨帆精彩的制作,杨帆现在代码进步不少
欣赏学习你做的美图美乐美帖,谢谢小辣椒鼓励,祝开心{:4_204:} 小辣椒 发表于 2026-4-13 22:33
但是小辣椒还是建议,你加的素材一点要和背景相符,这个背景是云动,山坡自然景象和纸飞机完全不得,你可以 ...
谢谢小辣椒的建议,是的,素材应该服务于主题{:4_204:} 画面漂亮,歌曲好听,欣赏杨帆的精彩音画。{:4_187:} 梦江南 发表于 2026-4-14 10:16
画面漂亮,歌曲好听,欣赏杨帆的精彩音画。
谢谢江南鼓励,祝开心天天{:4_204:} 杨帆 发表于 2026-4-13 23:04
谢谢影子鼓励,祝开心
问好杨帆,晚上好{:4_187:}
页:
[1]