背景视频同步播放
This commit is contained in:
@@ -11,6 +11,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// ===== 视频逻辑 =====
|
// ===== 视频逻辑 =====
|
||||||
const player = document.getElementById('player');
|
const player = document.getElementById('player');
|
||||||
|
const bgVideo = document.getElementById('bgVideo');
|
||||||
const videoWrap = document.getElementById('videoWrap');
|
const videoWrap = document.getElementById('videoWrap');
|
||||||
const videoPanel = document.getElementById('video');
|
const videoPanel = document.getElementById('video');
|
||||||
const includeLocalToggle = document.getElementById('includeLocalToggle');
|
const includeLocalToggle = document.getElementById('includeLocalToggle');
|
||||||
@@ -68,7 +69,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (!playlist.length) return;
|
if (!playlist.length) return;
|
||||||
index = (i + playlist.length) % playlist.length;
|
index = (i + playlist.length) % playlist.length;
|
||||||
const item = playlist[index];
|
const item = playlist[index];
|
||||||
|
try { player.crossOrigin = 'anonymous'; } catch {}
|
||||||
player.src = item.url;
|
player.src = item.url;
|
||||||
|
if (bgVideo) {
|
||||||
|
try {
|
||||||
|
bgVideo.muted = true;
|
||||||
|
bgVideo.loop = true;
|
||||||
|
bgVideo.setAttribute('playsinline', '');
|
||||||
|
bgVideo.src = item.url;
|
||||||
|
bgVideo.load();
|
||||||
|
bgVideo.play().catch(() => {});
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
// 已移除标题展示,无需设置文本
|
// 已移除标题展示,无需设置文本
|
||||||
player.load();
|
player.load();
|
||||||
if (videoPanel) videoPanel.style.setProperty('--progress', '0');
|
if (videoPanel) videoPanel.style.setProperty('--progress', '0');
|
||||||
@@ -186,16 +198,42 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (!isFinite(d) || d <= 0) return;
|
if (!isFinite(d) || d <= 0) return;
|
||||||
const p = Math.max(0, Math.min(1, t / d));
|
const p = Math.max(0, Math.min(1, t / d));
|
||||||
if (videoPanel) videoPanel.style.setProperty('--progress', String(p * 360));
|
if (videoPanel) videoPanel.style.setProperty('--progress', String(p * 360));
|
||||||
|
if (!bgCtx) return;
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - bgLastUpdate < 1500) return;
|
||||||
|
bgLastUpdate = now;
|
||||||
|
try {
|
||||||
|
bgCtx.drawImage(player, 0, 0, bgCanvas.width, bgCanvas.height);
|
||||||
|
const img = bgCtx.getImageData(0, 0, bgCanvas.width, bgCanvas.height).data;
|
||||||
|
let r = 0, g = 0, b = 0, cnt = 0;
|
||||||
|
for (let i = 0; i < img.length; i += 4) {
|
||||||
|
r += img[i]; g += img[i+1]; b += img[i+2]; cnt++;
|
||||||
|
}
|
||||||
|
if (cnt > 0) {
|
||||||
|
r = Math.round(r / cnt); g = Math.round(g / cnt); b = Math.round(b / cnt);
|
||||||
|
const mix = (c) => Math.round(c * 0.25 + 255 * 0.75);
|
||||||
|
const base = `rgb(${mix(r)},${mix(g)},${mix(b)})`;
|
||||||
|
const accent = `rgba(${r},${g},${b},0.2)`;
|
||||||
|
document.documentElement.style.setProperty('--bg-base', base);
|
||||||
|
document.documentElement.style.setProperty('--bg-accent', accent);
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 播放结束自动下一条
|
// 播放结束自动下一条
|
||||||
player.addEventListener('ended', () => { next(); });
|
player.addEventListener('ended', () => { next(); });
|
||||||
|
const bgCanvas = document.createElement('canvas');
|
||||||
|
bgCanvas.width = 32; bgCanvas.height = 18;
|
||||||
|
const bgCtx = bgCanvas.getContext('2d', { willReadFrequently: true });
|
||||||
|
let bgLastUpdate = 0;
|
||||||
|
player.addEventListener('loadeddata', () => { bgLastUpdate = 0; });
|
||||||
|
|
||||||
let lastLoggedVideo = '';
|
let lastLoggedVideo = '';
|
||||||
player.addEventListener('play', () => {
|
player.addEventListener('play', () => {
|
||||||
const cur = player.currentSrc || player.src || '';
|
const cur = player.currentSrc || player.src || '';
|
||||||
if (!cur || cur === lastLoggedVideo) return;
|
if (!cur || cur === lastLoggedVideo) return;
|
||||||
lastLoggedVideo = cur;
|
lastLoggedVideo = cur;
|
||||||
|
if (bgVideo) { try { bgVideo.play().catch(() => {}); } catch {} }
|
||||||
track({ event: 'video_play', page: location.pathname, url: cur, title: '' });
|
track({ event: 'video_play', page: location.pathname, url: cur, title: '' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
--radius: 6px;
|
--radius: 6px;
|
||||||
--shadow: 0 6px 14px rgba(226, 38, 38, 0.08);
|
--shadow: 0 6px 14px rgba(226, 38, 38, 0.08);
|
||||||
--shadow-hover: 0 8px 20px rgba(226, 38, 38, 0.12);
|
--shadow-hover: 0 8px 20px rgba(226, 38, 38, 0.12);
|
||||||
|
--bg-base: #ffffff;
|
||||||
|
--bg-accent: #fff5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
* { box-sizing: border-box; }
|
* { box-sizing: border-box; }
|
||||||
@@ -17,10 +19,14 @@ body {
|
|||||||
sans-serif;
|
sans-serif;
|
||||||
color: #333;
|
color: #333;
|
||||||
background:
|
background:
|
||||||
radial-gradient(1200px 400px at 10% -20%, #fff5f5 0%, transparent 40%),
|
radial-gradient(1200px 400px at 10% -20%, var(--bg-accent) 0%, transparent 40%),
|
||||||
linear-gradient(#ffffff, #ffffff);
|
linear-gradient(var(--bg-base), var(--bg-base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#bgVideoContainer { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
|
||||||
|
#bgVideoContainer video { width: 100%; height: 100%; object-fit: cover; filter: blur(36px) saturate(120%) brightness(1.05) contrast(1.05); transform: scale(1.06); opacity: 0.5; }
|
||||||
|
.page { position: relative; z-index: 1; }
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
max-width: var(--page-max);
|
max-width: var(--page-max);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
@@ -33,7 +39,7 @@ body {
|
|||||||
top: 0;
|
top: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
border: var(--border);
|
border: var(--border);
|
||||||
background: #fff;
|
background: rgba(255,255,255,0.95);
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -69,7 +75,7 @@ body {
|
|||||||
padding: 8px 14px;
|
padding: 8px 14px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--red);
|
border: 1px solid var(--red);
|
||||||
background: #fff;
|
background: rgba(255,255,255,0.92);
|
||||||
transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
|
transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id="bgVideoContainer" aria-hidden="true"><video id="bgVideo" muted autoplay loop playsinline></video></div>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<header class="menu">
|
<header class="menu">
|
||||||
<div class="menu__logo">菜单</div>
|
<div class="menu__logo">菜单</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user