Science
Player
A small animation clock for scenes. usePlayer ticks t (seconds) with requestAnimationFrame and gives you play, pause, seek, speed and looping. PlayerBar is a ready-made control bar for it.
Plot2D, Plot3D and ModelLab use these internally. Use them directly when you animate something else, such as a CSS demo, a canvas or a custom chart.
Import
tsx
import { usePlayer, PlayerBar } from "@indoku/ui"Anatomy
const player = usePlayer({ duration, loop?, autoPlay?, speed? })// player.t, player.playing, player.speed, player.duration// player.play(), pause(), toggle(), seek(t), setSpeed(s)<PlayerBar player={player} />Examples
Clock and control bar
Drive anything from player.t. Here a dot moves along a track.
tsx
function PlayerBasic() { const player = usePlayer({ duration: 4, loop: true }) const pct = (player.t / 4) * 100 return ( <div style={{ border: "1px solid var(--indoku-colors-border, #8884)", borderRadius: 8, overflow: "hidden" }}> <div style={{ position: "relative", height: 64 }}> <div style={{ position: "absolute", top: 20, left: `calc(${pct}% - ${pct * 0.24}px)`, width: 24, height: 24, borderRadius: 12, background: "#3b82f6" }} /> </div> <PlayerBar player={player} /> </div> )}Your own controls
autoPlay: false starts paused and loop: false stops at the end. Build any controls from the returned methods.
t = 0.00 s · paused · 1x
tsx
function PlayerCustom() { const player = usePlayer({ duration: 6, loop: false, autoPlay: false }) return ( <div style={{ display: "grid", gap: 8 }}> <div style={{ fontVariantNumeric: "tabular-nums" }}> t = {player.t.toFixed(2)} s · {player.playing ? "playing" : "paused"} · {player.speed}x </div> <div style={{ display: "flex", gap: 8 }}> <button onClick={player.play}>Play</button> <button onClick={player.pause}>Pause</button> <button onClick={() => player.seek(0)}>Reset</button> <button onClick={() => player.setSpeed(2)}>2x</button> </div> </div> )}Props
usePlayer(options)
| Prop | Type | Default | Description |
|---|---|---|---|
duration* | number | – | Length in seconds. 0 or less means static: the clock never ticks. |
loop | boolean | true | Wrap around at the end. When false, playback stops at duration. |
autoPlay | boolean | true (false with reduced motion) | Start playing right away. |
speed | number | 1 | Initial playback speed multiplier. |
PlayerBar
| Prop | Type | Default | Description |
|---|---|---|---|
player* | PlayerState | – | The object returned by usePlayer. |
* required. Style props and HTML attributes are accepted as well.
Accessibility
- The bar uses a native
buttonandinput[type=range], both labeled and keyboard accessible. prefers-reduced-motionturns autoplay off by default.
Notes
tis React state updated every frame, so keep components that read it small, or compute from it withuseMemo.- Changing
durationresets the clock to 0.
Created by @indokudev