KQ-1368 · CONTOUR/MARQUEE
Contour Marquee
A marquee whose rail is a curve: the sentence repeats seamlessly along a wave, an arch, a loop that passes behind itself, or any path you give it, every glyph turned to the curve's tangent. One phase is integrated from a velocity that only ever eases — to cruise, to a crawl under the pointer or focus, to rest when paused — on a critically damped spring that is springs.drift at the default coast; grabbing the line scrubs it 1:1 along the curve by projecting the pointer onto the path, and a flick hands its speed back to that spring. The rail is a button: Space or Enter pauses, Left and Right glide a word on springs.glide (Shift a whole sentence), Home re-centres it.
Fernworks · spring kiln
Thirty new glazes, fresh from the kiln
Drag along the line to scrub it. Left and Right move it by a word, Shift with an arrow by a whole sentence, Home centres it.cruising · 2.5 em/s · drag the line to scrub
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/contour-marquee
Props
- text
- string
- default —
- The sentence that rides the curve.
- as
- "p" | "h1" | "h2" | "h3" | "span" | "div"
- default "p"
- The element that carries the sentence for assistive technology.
- curve
- "wave" | "arch" | "loop" | string
- default "wave"
- The rail: a preset, or any SVG path d drawn in viewBox.
- viewBox
- string
- default "0 0 800 200"
- The coordinate box of a custom path; it also sets the box's proportions.
- speed
- number
- default 2.5
- Cruising speed along the curve, em per second.
- direction
- "forward" | "backward"
- default "forward"
- Which way the sentence travels along the path.
- size
- "sm" | "md" | "lg"
- default "md"
- Type scale against the inherited font size: 0.75, 1 or 1.35em.
- hoverSpeed
- number
- default 0.2
- Share of speed kept while the pointer is over the line or it has keyboard focus, 0 to 1.
- coast
- number
- default 0.5
- How long a flick carries before it eases back to cruise, 0 (brief) to 1 (long).
- separator
- string
- default "·"
- The mark between copies, drawn in accent.
- spacing
- number
- default 0.02
- Letter spacing, em.
- guide
- boolean
- default true
- Draw the rail under the type.
- fade
- number
- default 0.1
- Share of the width faded out at each end, 0 to 0.3.
- color
- string
- default "var(--foreground)"
- Type colour, any CSS colour.
- accent
- string
- default "var(--accent-bright)"
- The separator's colour, and the rail's while it is held.
- paused / defaultPaused
- boolean
- default false
- Controlled pause, or its initial value when uncontrolled.
- onPausedChange
- (paused: boolean) => void
- default —
- Fires from the press or key that paused or resumed the line, with the new state.
- onScrubChange
- (scrubbing: boolean) => void
- default —
- Fires when a drag along the line begins (true) and when it lets go (false).
- delay
- number
- default 0
- Wait this long after first coming into view before cruising, ms.
- disabled
- boolean
- default false
- No scrubbing or pausing; the line still cruises.
- className
- string
- default —
- Classes for the root; the type inherits its font size.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | — | The sentence that rides the curve. |
| as | "p" | "h1" | "h2" | "h3" | "span" | "div" | "p" | The element that carries the sentence for assistive technology. |
| curve | "wave" | "arch" | "loop" | string | "wave" | The rail: a preset, or any SVG path d drawn in viewBox. |
| viewBox | string | "0 0 800 200" | The coordinate box of a custom path; it also sets the box's proportions. |
| speed | number | 2.5 | Cruising speed along the curve, em per second. |
| direction | "forward" | "backward" | "forward" | Which way the sentence travels along the path. |
| size | "sm" | "md" | "lg" | "md" | Type scale against the inherited font size: 0.75, 1 or 1.35em. |
| hoverSpeed | number | 0.2 | Share of speed kept while the pointer is over the line or it has keyboard focus, 0 to 1. |
| coast | number | 0.5 | How long a flick carries before it eases back to cruise, 0 (brief) to 1 (long). |
| separator | string | "·" | The mark between copies, drawn in accent. |
| spacing | number | 0.02 | Letter spacing, em. |
| guide | boolean | true | Draw the rail under the type. |
| fade | number | 0.1 | Share of the width faded out at each end, 0 to 0.3. |
| color | string | "var(--foreground)" | Type colour, any CSS colour. |
| accent | string | "var(--accent-bright)" | The separator's colour, and the rail's while it is held. |
| paused / defaultPaused | boolean | false | Controlled pause, or its initial value when uncontrolled. |
| onPausedChange | (paused: boolean) => void | — | Fires from the press or key that paused or resumed the line, with the new state. |
| onScrubChange | (scrubbing: boolean) => void | — | Fires when a drag along the line begins (true) and when it lets go (false). |
| delay | number | 0 | Wait this long after first coming into view before cruising, ms. |
| disabled | boolean | false | No scrubbing or pausing; the line still cruises. |
| className | string | — | Classes for the root; the type inherits its font size. |