PageTransition is a layout wrapper that animates page entry and exit using Framer Motion’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/sys-core/llms.txt
Use this file to discover all available pages before exploring further.
AnimatePresence. Every route in sys-core is wrapped in PageTransition so that navigating between sections produces a polished interstitial effect: the incoming page fades in from a slightly scaled-down, blurred state while a burst of glowing cyan horizontal streaks fires across the screen, evoking a hyperspace jump or signal handshake.
How It Works
PageTransition receives the current route’s children and uses the current location.pathname (read via React Router’s useLocation) as the key prop on the inner motion.div. Changing the key causes React to unmount the old element and mount a new one, which is exactly what AnimatePresence needs to orchestrate coordinated enter and exit animations.
The component renders two layers:
- Content layer — a
motion.divkeyed to the pathname that wraps the actual page content. It animates opacity, scale, and a CSSblurfilter simultaneously. - Streak overlay — a second
motion.div, also keyed to the pathname, that renders 20 randomly-positioned horizontalcyan-signalbars. Each bar scales from zero width and shoots across the screen in~0.3 s, then the entire overlay fades to opacity0in0.5 s. The result is a brief “scanning” flash on every navigation.
Animation Values
All values below are taken directly from the compiled source of
components/layout/PageTransition.js. The streak positions and travel
distances are randomised at render time so each navigation looks slightly
different.Content layer
| Property | initial | animate | exit |
|---|---|---|---|
opacity | 0 | 1 | 0 |
scale | 0.95 | 1 | 1.05 |
filter (blur) | blur(10px) | blur(0px) | blur(10px) |
duration | — | 0.4 s | — |
ease | — | easeOut | — |
1.05 and re-blurs, suggesting the scene is receding before the new one materialises.
Streak overlay
| Property | Value |
|---|---|
| Count | 20 bars |
| Height | 2 px |
| Width | 50–250 px (random per bar) |
| Colour | #06b6d4 (cyan-signal) with a 10 px outer glow |
| Rotation | 0–360 ° (random per bar) |
scaleX animation | 0 → 1 over 0.3 s (easeIn) |
Horizontal travel (x) | 0 → ±0–500 px (random direction per bar) |
| Overlay fade-out | opacity: 1 → 0 over 0.5 s (easeOut) |
Usage
Wrap each route’s element withPageTransition inside the route definition. AnimatePresence must be placed at a level above the routes so it can observe component unmounts — in sys-core this is handled by passing mode="wait" to AnimatePresence around the Routes component:
Extending the Animation
To adjust timing or motion feel, edit thetransition objects in PageTransition.js:
Dependencies
PageTransition relies on Framer Motion’s PresenceContext internally.
AnimatePresence must wrap the router outlet at the app level — if it is
missing, exit animations will be skipped and the streak overlay will not fire
on navigation away from a page. In sys-core this is already wired up in
main.js where AnimatePresence mode="wait" wraps the Routes tree.| Package | Purpose |
|---|---|
framer-motion | motion.div animations and PresenceContext for mount/unmount detection |
react-router-dom | useLocation to derive the per-route key that triggers AnimatePresence |