From e720816d9a2ce4b5a4d1d87b7dbf463a0b7be315 Mon Sep 17 00:00:00 2001 From: M1ngdaXie <156019134+M1ngdaXie@users.noreply.github.com> Date: Thu, 26 Mar 2026 14:18:05 -0700 Subject: [PATCH] feat: add boot screen with apple logo and progress bar --- src/components/BootScreen/BootScreen.css | 38 ++++++++++++++++ src/components/BootScreen/BootScreen.tsx | 55 +++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/components/BootScreen/BootScreen.css diff --git a/src/components/BootScreen/BootScreen.css b/src/components/BootScreen/BootScreen.css new file mode 100644 index 0000000..88baa66 --- /dev/null +++ b/src/components/BootScreen/BootScreen.css @@ -0,0 +1,38 @@ +.boot-screen { + position: fixed; + inset: 0; + background: #000; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 48px; + z-index: 9999; +} + +.boot-logo { + display: flex; + align-items: center; + justify-content: center; +} + +.boot-apple { + width: 80px; + height: 80px; + fill: #fff; +} + +.boot-progress-track { + width: 200px; + height: 3px; + background: rgba(255,255,255,0.15); + border-radius: 2px; + overflow: hidden; +} + +.boot-progress-bar { + height: 100%; + background: #fff; + border-radius: 2px; + transition: width 0.05s linear; +} diff --git a/src/components/BootScreen/BootScreen.tsx b/src/components/BootScreen/BootScreen.tsx index c6a3151..1e850b7 100644 --- a/src/components/BootScreen/BootScreen.tsx +++ b/src/components/BootScreen/BootScreen.tsx @@ -1 +1,54 @@ -export default function BootScreen({ onComplete }: { onComplete: () => void }) { return
Loading...
; } +import { useEffect, useRef, useState } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import './BootScreen.css'; + +interface Props { + onComplete: () => void; +} + +export default function BootScreen({ onComplete }: Props) { + const [progress, setProgress] = useState(0); + const [visible, setVisible] = useState(true); + const doneRef = useRef(false); // guard against StrictMode double-fire + + useEffect(() => { + const interval = setInterval(() => { + setProgress(p => { + const next = p + 2; + return next > 100 ? 100 : next; + }); + }, 30); + return () => clearInterval(interval); + }, []); + + useEffect(() => { + if (progress >= 100 && !doneRef.current) { + doneRef.current = true; + const t1 = setTimeout(() => setVisible(false), 400); + const t2 = setTimeout(onComplete, 900); + return () => { clearTimeout(t1); clearTimeout(t2); }; + } + }, [progress, onComplete]); + + return ( + + {visible && ( + +
+ + + +
+
+
+
+ + )} + + ); +}