KQ-886 · GIF/LOOP

GIF Loop

A looping picture that plays only where it can be seen. Each clip is drawn rather than fetched — a seeded hash turns the clip's seed and frame index into a skyline, ground stripes and a marker arcing across the frame — and an IntersectionObserver rooted on the thread's own scroll box stops the tick when a clip falls below the visible threshold, landing a play badge on snap behind a fading scrim while a rail head travels one loop's width on a linear tween. Space or Enter pauses a clip by hand, aria-pressed carries that state, and under reduced motion nothing plays itself: the button becomes a frame step, one press per frame.

KQ-886 · GIF/LOOP
  1. Bay 3 door cycle
  2. Yard gate, 07:12
  3. Belt run, north line

Bay 3 door cycle · playing · frame 01 · 0 loops

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/gif-loop

Props

clips
GifClip[]
default —
The thread, oldest first: id, side, title, seed, frame count, time and delivery.
paused / defaultPaused
string[]
default []
Controlled or initial ids of clips paused by hand.
onPausedChange
(id: string, paused: boolean) => void
default —
Fires from the press or key that pauses or resumes a clip by hand.
onFrameChange
(id: string, frame: number) => void
default —
Fires on each frame a clip advances to.
onLoop
(id: string, loops: number) => void
default —
Fires as a clip wraps past its last frame, with its running loop count.
onInViewChange
(id: string, inView: boolean) => void
default —
Fires with the first reading and whenever a clip crosses the threshold.
fps
number
default 8
Frames a second while a clip plays.
threshold
number
default 0.6
Visible share a clip must hold in the viewport to keep playing.
viewportHeight
number
default 264
Height of the thread's scroll viewport, in pixels.
viewportRef
React.RefObject<HTMLDivElement | null>
default —
Hands the scroll viewport to the host so it can scroll the thread itself.
peerName
string
default "Them"
Names the other side in delivery and clip sentences.
label
string
default —
Names the scrollable thread region for assistive technology.