Logo Trace Loader
A React loader where a short dash orbits a logo's outline; on completion it closes into a full stroke and fades in the fill. Defaults to the WebberUI brand curve, accepts any path and can run as a full-page overlay.
Turn your brand mark into a loading indicator. While loading, a short dash keeps orbiting the logo's outline over a faint full-length track; once isComplete turns true (or loading turns false), the dash grows forward into the full outline and the fill fades in — an open line has nothing to fill, so its stroke shifts from the mid-tone to the main colour instead. onDone fires once when the whole sequence ends. The default path is the WebberUI brand curve; pass your own path and viewBox to use any mark. Turn on fullscreen to cover the page with a translucent blurred overlay that fades out when done.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add logo-trace-loader.enPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<LogoTraceLoader/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
Installation
npx webberui@latest add https://webberui.com/r/logo-trace-loader.en.jsonOr, once registries are configured in components.json, install it as @webberui/logo-trace-loader.
Usage
import { LogoTraceLoader } from "@/components/ui/logo-trace-loader";
const [loading, setLoading] = React.useState(true);
const [done, setDone] = React.useState(false);
// Set isComplete to true when the data arrives; onDone fires after the animation
<LogoTraceLoader
loading={loading}
isComplete={done}
onDone={() => setLoading(false)}
/>
// Use your own closed path; the fill fades in on completion
<LogoTraceLoader
path="M18 8H46A10 10 0 0 1 56 18V46A10 10 0 0 1 46 56H18A10 10 0 0 1 8 46V18A10 10 0 0 1 18 8Z"
fill="rgb(16 185 129 / 0.18)"
strokeWidth={5}
isComplete={done}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | true | Whether loading is in progress; switching to false counts as complete and starts the close |
isComplete | boolean | false | Whether loading is complete; switching to true closes into a full outline, then colours it |
path | string | WebberUI brand curve | SVG path string to trace |
viewBox | string | "0 0 64 64" | SVG viewBox; must match the coordinate system of path |
size | number | 64 | Mark size in px; the element has a fixed width and height to avoid layout shift |
strokeWidth | number | 7.5 | Stroke width when complete (viewBox units); the faint loop-phase track is half of it |
loopDurationSeconds | number | 1.4 | Seconds for the short dash to complete one orbit |
fillFadeSeconds | number | 0.35 | Seconds for the fill (or stroke colour change) to fade in on completion |
fill | string | "none" | Fill for a closed path; with none the stroke changes colour instead |
fullscreen | boolean | false | Show as a full-page overlay that fades out when done |
label | string | "載入中" (Loading) | Loading text for screen readers, also shown visibly under reduced motion |
onDone | () => void | — | Called once after the whole completion animation has finished |
className | string | — | Forwarded to the outermost container |
How it works
- The phases run loop → closingOutline → fadingFill → done. The close is a fixed 360ms (
cubic-bezier(0.23, 1, 0.32, 1)) and the fill fade usesfillFadeSeconds; phase switches are scheduled withsetTimeoutfrom the computed total rather thananimationend, soonDoneis never missed if an element unmounts or an animation is interrupted. - The short dash is drawn on a
pathLength=1path withstrokeDasharrayof0.16 0.84andstrokeDashoffsetmoving linearly from 0 to −1, so any shape loops seamlessly; on close the dash grows forward from wherever it is into1 0, without jumping back to the start. - If the loader starts out complete (for example
loading={false}), it shows the final state directly without replaying the close or callingonDone; switchingloadingback totruerestarts from the loop. - Colour variables:
--wb-ltl-color(main colour, defaults tocurrentColor),--wb-ltl-track(the mid-tone after closing and before colouring, derived fromcurrentColormixed with transparent by default) and--wb-ltl-ease(easing for the stroke colour change). Setting a text colour throughclassNamerecolours the whole set. - Fullscreen mode is a
fixed inset-0 z-50translucent blurred overlay (bg-white/80,bg-neutral-950/80in dark mode) that fades in and out over 200ms.
Accessibility
- The wrapper is a
role="status",aria-live="polite"region that announceslabelwhile loading and "載入完成" (Loaded) when done - The SVG is
aria-hidden, so the animation itself is never read out by assistive technology - In fullscreen mode the status text lives outside the overlay, so the completion message is still announced after the overlay fades out
- When the user has reduce motion enabled at the system level there is no orbit: while loading it shows a static, faint full outline with visible
labeltext, and on completion it jumps to the final state and callsonDoneon the next tick
Streak Flame Counter
A Duolingo-style streak flame — the flame flares when the number goes up and changes color at milestones
Alert Callout
An alert callout React component in five semantic variants that fades up on entry, collapses by height when dismissed so content below slides into place, and gives its icon a small pop when live content updates.