/* 首页入场:复用 c0lor-MAG 的共享元素交接思路。 中央品牌按真实 DOM 尺寸飞向移动端主页左上角,底层主页同步显现。 */ (() => { const ENTRY_ORBIT_ASSETS = Array.from({ length: 11 }, (_, index) => `tv-orbit-assets/tv-${String(index + 1).padStart(2, '0')}.png` ); const ENTRY_FLIGHT_MS = 720; const ENTRY_EASE = 'cubic-bezier(.19,.88,.18,1)'; const ENTRY_ORBIT_SECONDS = 195; // Match the reference orbit cadence. function EntryOrbitRing({ count, radius, duration, reverse = false, outer = false }) { return ( ); } function EntryIntro({ onRevealStart, onHandoff, onComplete }) { const [transitioning, setTransitioning] = React.useState(false); const [testDataCount, setTestDataCount] = React.useState(12684); const brandRef = React.useRef(null); const shellRef = React.useRef(null); const flightRef = React.useRef(null); const flightAnimationRef = React.useRef(null); const timerRef = React.useRef(null); const startedRef = React.useRef(false); const reducedMotion = !!( window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches ); React.useEffect(() => { shellRef.current?.focus({ preventScroll: true }); timerRef.current = window.setInterval(() => { setTestDataCount((value) => value + Math.floor(Math.random() * 3) + 1); }, 1400); return () => window.clearInterval(timerRef.current); }, []); React.useEffect(() => { return () => { flightAnimationRef.current?.cancel(); flightRef.current?.remove(); }; }, []); const finishWithoutFlight = React.useCallback(() => { onRevealStart(); onHandoff(); window.setTimeout(onComplete, reducedMotion ? 90 : 140); }, [onComplete, onHandoff, onRevealStart, reducedMotion]); const startTransition = React.useCallback((skipFlight = false) => { if (startedRef.current) return; startedRef.current = true; window.clearInterval(timerRef.current); setTransitioning(true); if (skipFlight || reducedMotion) { finishWithoutFlight(); return; } const source = brandRef.current; const target = document.querySelector('.entry-brand-target'); if (!source || !target) { finishWithoutFlight(); return; } const from = source.getBoundingClientRect(); const to = target.getBoundingClientRect(); if (!from.width || !from.height || !to.width || !to.height) { finishWithoutFlight(); return; } onRevealStart(); const flight = source.cloneNode(true); flight.removeAttribute('id'); flight.setAttribute('aria-hidden', 'true'); flight.classList.add('entry-flight-brand'); Object.assign(flight.style, { left: `${from.left}px`, top: `${from.top}px`, width: `${from.width}px`, height: `${from.height}px`, }); document.body.appendChild(flight); flightRef.current = flight; source.style.visibility = 'hidden'; const scale = Math.min(to.width / from.width, to.height / from.height); const endWidth = from.width * scale; const endHeight = from.height * scale; const endLeft = to.left + (to.width - endWidth) / 2; const endTop = to.top + (to.height - endHeight) / 2; const dx = endLeft - from.left; const dy = endTop - from.top; const flightAnimation = flight.animate([ { transform: 'translate3d(0,0,0) scale(1)', opacity: 1, offset: 0 }, { transform: `translate3d(${dx * 0.92}px,${dy * 0.92}px,0) scale(${scale * 1.055})`, opacity: 1, offset: 0.82, }, { transform: `translate3d(${dx}px,${dy}px,0) scale(${scale})`, opacity: 1, offset: 1 }, ], { duration: ENTRY_FLIGHT_MS, easing: ENTRY_EASE, fill: 'forwards', }); flightAnimationRef.current = flightAnimation; flightAnimation.finished.then(() => { /* 目标与飞行体使用同一套品牌 DOM;先同步显露目标,再在下一帧移除飞行体。 不做二次淡变,避免字体抗锯齿叠加和 React 提交时序造成落点闪一下。 */ target.style.opacity = '1'; onHandoff(); window.requestAnimationFrame(() => { flight.remove(); flightRef.current = null; onComplete(); }); }).catch(() => { flight.remove(); flightRef.current = null; target.style.opacity = '1'; onHandoff(); onComplete(); }); }, [finishWithoutFlight, onComplete, onHandoff, onRevealStart, reducedMotion]); React.useEffect(() => { const onKeyDown = (event) => { if (event.key === 'Escape') startTransition(true); }; window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [startTransition]); return (

买东西, 先看

— 基于{testDataCount.toLocaleString('zh-CN')}条实测数据

); } window.EntryIntro = EntryIntro; })();