feat: story-journey immersive layer (progress, scene focus, floating orbs)
All checks were successful
Deploy / deploy (push) Successful in 2s

This commit is contained in:
Chen Gu
2026-04-24 09:31:21 +08:00
parent dbd2159429
commit 82a2d231c3
4 changed files with 178 additions and 3 deletions

View File

@@ -7,6 +7,7 @@
// ═══ 星空粒子系统 ═══
const canvas = document.getElementById('starfield');
if (!canvas) return;
const ctx = canvas.getContext('2d');
let width, height, stars, nebulas;
let animationId;
@@ -133,6 +134,55 @@
});
}
// ═══ 场景滚动进度 + 旅程节点高亮 ═══
function setupStoryJourney() {
const body = document.getElementById('storyBody');
const progress = document.getElementById('storyProgress');
if (!body || !progress) return;
const scenes = Array.from(body.querySelectorAll(':scope > p'));
if (!scenes.length) return;
const onScroll = () => {
const rect = body.getBoundingClientRect();
const total = Math.max(body.scrollHeight - window.innerHeight, 1);
const scrolled = Math.min(Math.max(-rect.top, 0), total);
const ratio = scrolled / total;
progress.style.width = `${(ratio * 100).toFixed(2)}%`;
let activeIndex = 0;
let minDistance = Infinity;
scenes.forEach((p, idx) => {
const r = p.getBoundingClientRect();
const d = Math.abs(r.top - window.innerHeight * 0.35);
if (d < minDistance) {
minDistance = d;
activeIndex = idx;
}
});
scenes.forEach((p, idx) => p.classList.toggle('active-scene', idx === activeIndex));
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
}
// ═══ 漂浮光团轻微视差 ═══
function setupOrbsParallax() {
const orbs = document.querySelectorAll('.story-orb');
if (!orbs.length) return;
window.addEventListener('scroll', () => {
const y = window.scrollY;
orbs.forEach((orb, i) => {
const factor = (i + 1) * 0.04;
const xShift = Math.sin(y * 0.002 + i) * 10;
const yShift = y * factor;
orb.style.transform = `translate(${xShift}px, ${yShift}px)`;
});
}, { passive: true });
}
// ═══ 初始化 ═══
window.addEventListener('resize', () => {
resize();
@@ -146,6 +196,8 @@
setupReveal();
setupParallax();
setupGlow();
setupStoryJourney();
setupOrbsParallax();
});
})();