Vinyl Record Player
A playable vinyl turntable: the record spins, the tonearm swings in, and you can drag the record to scratch.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
The vinyl grooves and the center label are drawn with CSS radial gradients; while playing, the record spins at a constant speed and the tonearm springs in and settles onto the disc. Drag the record directly to scratch it — the angular velocity tracks your hand exactly, and once you let go it smoothly settles back to playback speed. A play/pause button and a track information row are included.
npx shadcn@latest add "https://webberui.com/r/vinyl-record-player.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<VinylRecordPlayer />
Installation
npx shadcn@latest add "https://webberui.com/r/vinyl-record-player.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/vinyl-record-player.
Usage
import { VinylRecordPlayer } from "@/components/ui/vinyl-record-player";
<VinylRecordPlayer
track={{ title: "Neon Night Run", artist: "The Platform Band", hue: 265 }}
playing
onPlayingChange={(playing) => console.log(playing)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
track | VinylTrack | a default track | Track information { title, artist, hue? }, where hue (0–360) decides the label and ambient light color |
playing | boolean | — | Playback state; the turntable starts and stops in sync when it changes externally, and the component's own button can still toggle it |
onPlayingChange | (playing: boolean) => void | — | Callback when the play/pause button is pressed |
rpm | number | 33.3 | Record speed (RPM), which affects the angular velocity of the spin |
size | number | 224 | Record diameter (px) |
className | string | — | Forwarded to the outermost container |
Accessibility
- The play/pause button provides an
aria-label, and the status text (now playing / paused) updates in step with playback - The purely visual turntable and tonearm areas are marked
aria-hidden, and the track information is presented as plain text in the information row, which avoids it being announced twice - When the user has "reduce motion" enabled at the system level: the record does not spin, the tonearm goes straight to position without a spring, and letting go after a scratch does not settle back with momentum — the playback controls are unaffected
- Scratching is an enhanced interaction for mouse and touch; keyboard users can complete every core operation through the buttons
- The rAF loop stops automatically once the turntable is idle and completely still, and also pauses when it scrolls out of the viewport, so it does not cost performance
Waveform Scrubber
An audio waveform progress bar you can drag to seek, with the played region highlighted.
Lightbox Gallery (React)
A React thumbnail wall that opens a full-screen lightbox: the image morphs in from its thumbnail as a shared element, with wheel/pinch zoom and drag panning, double-tap zoom, swipe and keyboard navigation, a counter and caption bar, a bottom thumbnail strip, and Esc or backdrop to close.