苦乐自度
<!DOCTYPE html><html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="never">
<title>苦乐自度</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Liu+Jian+Mao+Cao&family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+KuaiLe&family=ZCOOL+QingKe+HuangYou&display=swap");
#papa {position: relative;display: grid;place-items: center;margin: 30px 0;width: 1280px;height: 750px;left: calc(50% - 81px);transform: translateX(-50%);box-shadow: 3px 3px 6px gray;overflow: hidden;z-index: 1;background:var(--bg1);--bg1:#000 url('https://pic1.imgdb.cn/i/0342wsAfkXM1pnbYnjakgw.gif') no-repeat center/cover;--bg2:#000 url('https://s3.bmp.ovh/2026/09/21/9zfOqpJU.png') no-repeat center/cover;}
#mutedbnt{position:absolute; z-index: 10; width: 50px; height: 50px; top: 5%; left: 5%; cursor: pointer; }
.btnFull{ width:25px; height:25px; position:absolute; z-index: 10; top: 5%; right: 5%; background:url('https://pic1.imgdb.cn/item/6774df83d0e0a243d4ed4fd7.png') no-repeat center/cover; cursor:pointer; border:none;outline: none; box-shadow: 0 0 8px rgba(255,255,255,0.25); transition: transform 0.15s ease, box-shadow 0.15s ease;opacity: 0; }
#papa:hover .btnFull {opacity: .98; }
#lrc { right:30px; bottom:30px; background: linear-gradient(to right, HotPink, LightSkyBlue, Gold); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; color: transparent; font: bold 3.0rem 'Long Cang','ZCOOL KuaiLe','Ma Shan Zheng','华文琥珀',STLiti,"宋体", "SimSun", "Microsoft YaHei", sans-serif !important;}
.time-display { position: absolute; left:50%;top:5%; transform: translateX(-50%); z-index: 20; font-size: 35px; font-weight: 600; font-family:'ZCOOL KuaiLe','Ma Shan Zheng', '华文楷体', 'KaiTi', '楷体', 'STKaiti', serif; letter-spacing: 1px; pointer-events: none; background: linear-gradient( 135deg, #ff0000, #ff7700, #ffff00, #00ff00, #0000ff, #8b00ff, #ff00ff ); background-size: 300% 300%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; animation: rainbowMove 8s ease-in-out infinite alternate; text-shadow: 0 0 30px rgba(255, 255, 255, 0.1); filter: drop-shadow(0 0 15px rgba(255, 215, 0, 0.2)); }
@keyframes rainbowMove { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
.time-display.stop { animation-play-state: paused; }
#pic { position: absolute; left:15px; bottom:30px; width:400px; height: 250px; mix-blend-mode: screen; mask:url("https://pic1.imgdb.cn/i/0347Idy38SXalwDqQlOS2r.png") no-repeat center/80% 80%;-webkit-mask:url("https://pic1.imgdb.cn/i/0347Idy38SXalwDqQlOS2r.png") no-repeat center/80% 80%; z-index:3; }
.vid{position:absolute;width:120%;height:120%;top:-10%;left:-10%;object-fit:cover;mask:radial-gradient(transparent 20%,red);-webkit-mask:radial-gradient(transparent 20%,red);mix-blend-mode:screen;pointer-events:none;z-index:2;}
.drop-container { position: absolute; bottom: 150px; left: 65px; width: 450px; height: 400px; z-index: 2; overflow: visible; background-color: transparent; }
#dropCanvas { display: block;z-index: 10; width: 100%; height: 100%; background-color: transparent; }
</style>
</head>
<body>
<div id="papa">
<div class="drop-container">
<canvas id="dropCanvas" width="900" height="800"></canvas>
</div>
<audio id="aud"></audio>
<video class="vid" src="https://img2.tukuppt.com/video_show/15653652/00/80/83/60d0445e4511e_10s_big.mp4" autoplay loop muted></video>
<video class="vid" src="https://img2.tukuppt.com/video_show/15653652/01/59/07/63806a6eb7241.mp4" autoplay loop muted></video>
<img src="https://pic1.imgdb.cn/item/6a03cf00c05e72d91720910b.gif" id="mutedbnt" onClick="pc()" title="暂停/空格键";/>
<button id="btnFull" class="btnFull" title="全屏"></button>
<div id="lrc" data-lrc="苦乐自度">苦乐自度</div>
<div class="time-display" id="timeDisplay">00:00 /苦乐自度/ 00:00</div>
<video id ="pic" src="https://video-qn.51miz.com/preview/video/00/00/65/26/V-652636-1D4CC24F.mp4" autoplay loop preload="auto" playsinline muted></video>
</div>
<script type="module">
import lrc from 'https://638183.freep.cn/638183/web/lrc/yslrc-only.js';
aud.src = 'https://aod.cos.tx.xmcdn.com/storages/300e-audiofreehighqps/F4/78/GKwRIW4NyasAABQvqQSSg04y.m4a';
aud.loop = true;
aud.volume = 1.0;
aud.preload = 'auto';
var geci = `
苦乐自度
走过了风雨 尝过了酸楚
才懂这人生 有甜也有苦
繁华和落寞 谁也留不住
悲欢离合 终究要落幕
受过了委屈 走过了弯路
慢慢才明白 凡事靠自渡
不必去抱怨 不必去倾诉
默默扛起 生活的包袱
人生苦乐要自渡
悲欢离合自己悟
再难的路 不认输
心中有光 就不孤独
人生苦乐要自渡
起起落落是归宿
心怀善良 踏平坎坷
笑着走完 这一段旅途
人生这趟 单行路
苦乐悲欢 皆自渡
`;
lrc(papa, geci, 0, 0);
</script>
<script>
const papa = document.getElementById('papa');
const timeDisplay = document.querySelector('.time-display');
var pic = document.getElementById("mutedbnt");
const vids = document.querySelectorAll('video');
const bg1 = getComputedStyle(papa).getPropertyValue('--bg1');
const bg2 = getComputedStyle(papa).getPropertyValue('--bg2');
const btnFull = document.getElementById('btnFull');
var mseek = false;
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;
}
aud.addEventListener('timeupdate', () => {
timeDisplay.textContent = `${toMin(aud.currentTime)}/苦乐自度/${toMin(aud.duration)}`;
});
function pc() {
if (aud.paused) {
aud.play();
vids.forEach(vid =>vid.play());
pic.src = "https://pic1.imgdb.cn/item/6a03cf00c05e72d91720910b.gif";
papa.style.background = bg1;
pic.title="暂停/空格键";window.__dropRunning = true;
timeDisplay.classList.remove('stop');
}
else {
aud.pause();
vids.forEach(vid => vid.pause());
pic.src = "https://pic1.imgdb.cn/item/68e9c0c2c5157e1a886337ae.png";
papa.style.background = bg2;
pic.title="播放/空格键"; window.__dropRunning = false;
timeDisplay.classList.add('stop');
}
}
btnFull.addEventListener('click', () => {
if (!document.fullscreenElement) {papa.requestFullscreen().catch(() => {});}
else {document.exitFullscreen();}
});
document.addEventListener('fullscreenchange', () => {
if (document.fullscreenElement) {
btnFull.style.background = 'url(https://pic1.imgdb.cn/item/6774df8bd0e0a243d4ed4fd9.png) no-repeat center/cover';
btnFull.title = '退出';
} else {
btnFull.style.background ='url(https://pic1.imgdb.cn/item/6774df83d0e0a243d4ed4fd7.png) no-repeat center/cover';
btnFull.title = '全屏';
}
});
['contextmenu', 'dragstart', 'selectstart'].forEach(type =>
papa.addEventListener(type, e => e.preventDefault())
);
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
if (!aud.paused) {
aud.pause();
}
} else {
if (aud.paused) {
aud.play().catch(()=>{});
}
}
});
document.addEventListener ('keydown', function (e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (e.code === 'Space') { e.preventDefault ();
pc(); }
});
(function initDrop() {
window.__dropRunning = false;
const canvas = document.getElementById('dropCanvas');
const ctx = canvas.getContext('2d');
const W = canvas.width;
const H = canvas.height;
const scale = 3.2;
const baseX = W / 2;
const baseY = 30;
let dropY = baseY;
const speed = 1.2;
const WATER_LINE = H - 120;
let rippleRadius = 0;
let rippleActive = false;
const rippleMaxRadius = 350;
let rippleOpacity = 0;
let ripplePhase = 0;
let fragments = [];
let isShattered = false;
let shatterTimer = 0;
const pts = [
{ x: 50, y: 12 }, { x: 32, y: 46 }, { x: 32, y: 60 },
{ x: 32, y: 74 }, { x: 40, y: 88 }, { x: 50, y: 88 },
{ x: 60, y: 88 }, { x: 68, y: 74 }, { x: 68, y: 60 },
{ x: 68, y: 46 }, { x: 50, y: 12 }
];
function createFragments(cx, cy) {
const frags = [];
const count = 30 + Math.floor(Math.random() * 20);
for (let i = 0; i < count; i++) {
const angle = Math.random() * Math.PI * 2;
const spd = 2 + Math.random() * 6;
const size = 3 + Math.random() * 8;
const life = 30 + Math.random() * 40;
frags.push({
x: cx + (Math.random() - 0.5) * 15,
y: cy + (Math.random() - 0.5) * 15,
vx: Math.cos(angle) * spd * (0.5 + Math.random()),
vy: Math.sin(angle) * spd * (0.5 + Math.random()) - 2,
size: size,
life: life,
maxLife: life,
opacity: 0.7 + Math.random() * 0.3,
rotation: Math.random() * Math.PI * 2,
rotationSpeed: (Math.random() - 0.5) * 0.2
});
}
return frags;
}
function drawFrame() {
if (!window.__dropRunning) {
requestAnimationFrame(drawFrame);
return;
}
ctx.clearRect(0, 0, W, H);
dropY += speed;
const currentOffsetX = baseX;
const dropTipY = dropY + 50 * scale + 20;
if (dropTipY >= WATER_LINE && !rippleActive && !isShattered) {
rippleActive = true;
rippleRadius = 12;
rippleOpacity = 0.7;
ripplePhase = 0;
isShattered = true;
shatterTimer = 0;
const cx = currentOffsetX;
const cy = dropTipY;
fragments = createFragments(cx, cy);
}
if (isShattered) {
shatterTimer++;
let allDead = true;
fragments.forEach(f => {
f.x += f.vx;
f.y += f.vy;
f.vy += 0.08;
f.vx *= 0.99;
f.vy *= 0.99;
f.life--;
f.rotation += f.rotationSpeed;
if (f.life > 0) allDead = false;
});
if (allDead || shatterTimer > 120) {
isShattered = false;
fragments = [];
dropY = baseY;
rippleActive = false;
rippleRadius = 0;
rippleOpacity = 0;
}
}
fragments.forEach(f => {
const op = f.opacity * (f.life / f.maxLife);
if (op > 0.01) {
ctx.save();
ctx.globalAlpha = op * 0.9;
ctx.translate(f.x, f.y);
ctx.rotate(f.rotation);
const w = f.size;
const h = f.size * (0.5 + Math.random() * 0.5);
ctx.beginPath();
ctx.ellipse(0, 0, w / 2, h / 2, 0, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255,255,255,${op * 0.9})`;
ctx.shadowColor = `rgba(255,255,255,${op * 0.3})`;
ctx.shadowBlur = 6;
ctx.fill();
ctx.restore();
}
});
if (rippleActive) {
const cx = currentOffsetX;
const cy = WATER_LINE + 20;
rippleRadius += 5.0;
ripplePhase += 0.05;
if (rippleRadius > rippleMaxRadius) rippleActive = false;
const progress = rippleRadius / rippleMaxRadius;
const currentOpacity = rippleOpacity * (1 - progress * progress * 0.9) * 0.85;
if (currentOpacity > 0.003) {
ctx.save();
const layers = [
{ radius: 0.98, yOff: 30, opacity: 0.1, width: 1.2 },
{ radius: 0.84, yOff: 22, opacity: 0.25, width: 1.8 },
{ radius: 0.65, yOff: 14, opacity: 0.5, width: 2.5 },
{ radius: 0.42, yOff: 7, opacity: 0.75, width: 3.2 },
{ radius: 0.22, yOff: 2, opacity: 0.92, width: 3.8 }
];
layers.forEach(layer => {
ctx.beginPath();
ctx.ellipse(cx, cy + layer.yOff,
rippleRadius * layer.radius,
rippleRadius * layer.radius * 0.34,
0, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(255,255,255,${currentOpacity * layer.opacity})`;
ctx.lineWidth = layer.width;
ctx.stroke();
});
const grad = ctx.createRadialGradient(cx, cy, 2, cx, cy, rippleRadius * 0.28);
grad.addColorStop(0, `rgba(255,255,255,${currentOpacity * 0.6})`);
grad.addColorStop(0.4, `rgba(255,255,255,${currentOpacity * 0.2})`);
grad.addColorStop(1, 'rgba(255,255,255,0)');
ctx.beginPath();
ctx.arc(cx, cy, rippleRadius * 0.28, 0, Math.PI * 2);
ctx.fillStyle = grad;
ctx.fill();
ctx.restore();
}
}
if (!isShattered) {
const shifted = pts.map(p => ({
x: (p.x - 50) * scale + currentOffsetX,
y: (p.y - 50) * scale + baseY + 50 * scale + dropY
}));
ctx.save();
ctx.beginPath();
ctx.moveTo(shifted.x, shifted.y);
ctx.bezierCurveTo(shifted.x, shifted.y, shifted.x, shifted.y, shifted.x, shifted.y);
ctx.bezierCurveTo(shifted.x, shifted.y, shifted.x, shifted.y, shifted.x, shifted.y);
ctx.bezierCurveTo(shifted.x, shifted.y, shifted.x, shifted.y, shifted.x, shifted.y);
ctx.bezierCurveTo(shifted.x, shifted.y, shifted.x, shifted.y, shifted.x, shifted.y);
ctx.closePath();
ctx.fillStyle = 'rgba(255,255,255,0.45)';
ctx.fill();
const centerX = (shifted.x + shifted.x) / 2;
const centerY = (shifted.y + shifted.y) / 2;
ctx.beginPath();
ctx.ellipse(centerX - 6, centerY - 10, 5, 3, 0, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.fill();
ctx.restore();
}
requestAnimationFrame(drawFrame);
}
drawFrame();
})();
aud.play().then(() => {
window.__dropRunning = true;
}).catch(e => {
console.log('自动播放被阻止,点击按钮播放');
window.__dropRunning = false;
});
</script>
</body>
</html>
代码来自马黑黑老师、llz123老师分享作品,在此一并表示感谢 友友制作漂亮,谢谢分享!
页:
[1]