// Author: fruit.com.cn import { useLayoutEffect, useRef } from 'react'; const DURATION = 420; const FADE = 180; export function HeroTransition({ data, onDone }) { const ref = useRef(null); useLayoutEffect(() => { if (!data) return undefined; const node = ref.current; if (!node) return undefined; const rect = data; const scale = Math.max(window.innerWidth / rect.width, window.innerHeight / rect.height) * 1.04; const tx = (window.innerWidth - rect.width * scale) / 2 - rect.left; const ty = (window.innerHeight - rect.height * scale) / 2 - rect.top; const expand = node.animate( [ { transform: 'translate(0, 0) scale(1)', borderRadius: '12px' }, { transform: `translate(${tx}px, ${ty}px) scale(${scale})`, borderRadius: '0px' }, ], { duration: DURATION, easing: 'cubic-bezier(.2, .7, .3, 1)', fill: 'forwards' }, ); expand.onfinish = () => { const fade = node.animate([{ opacity: 1 }, { opacity: 0 }], { duration: FADE, fill: 'forwards' }); fade.onfinish = onDone; }; return () => expand.cancel(); }, [data, onDone]); if (!data) return null; const rect = data; return ( ); }