/* ============================================================ CHAINUS — Download easter egg: mascot CTA Exported: MascotDownload ============================================================ */ ['mascot/beaver-hey.png', 'mascot/beaver-like.png', 'mascot/beaver-clap.png'].forEach((s) => { const i = new Image(); i.src = s; }); function requestBetaAccess(t) { window.scrollTo({ top: document.documentElement.scrollHeight, behavior: reduceMotion() ? 'auto' : 'smooth' }); window.setTimeout(() => document.getElementById('contact-email')?.focus(), reduceMotion() ? 0 : 700); } function MascotDownload({ label, t, big = false, onClick }) { const wrapRef = useRef(null); const holdRef = useRef(null); const [awake, setAwake] = useState(false); const [linked, setLinked] = useState(false); useEffect(() => { const wrap = wrapRef.current; if (!wrap || !window.isFinePointer || !isFinePointer() || reduceMotion()) return; let raf = 0; const cur = { r: 0 }; const tgt = { r: 0 }; const onMove = (e) => { const r = wrap.getBoundingClientRect(); const cx = r.left + r.width / 2, cy = r.top + r.height / 2; const dx = e.clientX - cx, dy = e.clientY - cy; const near = Math.hypot(dx, dy) < 300; setAwake(near); tgt.r = near ? Math.max(-14, Math.min(14, dx * 0.045)) : 0; }; const loop = () => { cur.r += (tgt.r - cur.r) * 0.12; if (holdRef.current) holdRef.current.style.setProperty('--lean', cur.r.toFixed(2) + 'deg'); raf = requestAnimationFrame(loop); }; raf = requestAnimationFrame(loop); window.addEventListener('mousemove', onMove, { passive: true }); return () => { cancelAnimationFrame(raf); window.removeEventListener('mousemove', onMove); }; }, []); const fire = () => { setLinked(true); window.setTimeout(() => setLinked(false), 1600); if (onClick) onClick(); else requestBetaAccess(t); }; const pose = linked ? 'mascot/beaver-like.png' : 'mascot/beaver-hey.png'; const bubble = linked ? (t.dir === 'zh' ? '走起!' : 'Let\u2019s go!') : (t.dir === 'zh' ? '嗨!一起上链' : 'Hi! Tap to join'); return ( setAwake(true)} onMouseLeave={() => setAwake(false)} > ); } Object.assign(window, { MascotDownload, requestBetaAccess });