23rd

Phosphor Score

Vertical CRT sheet music — notes slide down a grand staff, bloom and flare at the playhead, then fade with a phosphor afterglow.

A falling score, not a piano roll. A grand staff of beamed runs, chords, slurs and dynamics scrolls down to a playhead: each note brightens as it arrives, blooms and flares as it plays, then fades with a phosphor afterglow. Default theme="auto" follows the site — phosphor green in dark, forest ink in light, both on the page background. glow is 0–100 (default 50) and stays a tight halo on the note. Change Seed to crossfade to a new score. Press d to toggle the theme.

Preview

Props
#147a3a
50
1.35
1
23
0
0
0

Slow camera drift around the plane

Installation

pnpm dlx shadcn@latest add @23rd/phosphor-score

Or install straight from the public GitHub source registry:

pnpm dlx shadcn@latest add radiumcoders/23rd.dev/phosphor-score

Usage

Give the parent a size. The canvas fills the parent and fades out at its top and bottom edges on its own.

"use client"

import { PhosphorScore } from "@/components/ui/phosphor-score"

export function HeroScore() {
  return (
    <div className="relative h-svh w-full bg-background">
      <PhosphorScore />
    </div>
  )
}

Lock a theme or push the bloom. Omit color to follow light / dark.

<PhosphorScore theme="light" glow={50} />
<PhosphorScore theme="dark" color="#4DFF6A" glow={50} />

Change the viewing angle. The plane turns about the playhead in perspective, like CSS rotateX() rotateY() rotateZ(), and fades out as it recedes.

<PhosphorScore rotateX={50} />
<PhosphorScore rotateX={35} rotateY={-20} rotateZ={8} />

prefers-reduced-motion: reduce holds a still frame of the score and stops drawing. The animation also pauses while the canvas is off-screen or the tab is hidden.

Props

PropTypeDefault
colorstringtheme phosphor / forest ink — any CSS color
glownumber50 — 0–100, halo size at the playhead
speednumber1.35 — beats per second
densitynumber1 — 0.35–1.85, how packed the notation is
swaybooleantrue — slow camera drift
seednumber23 — a new seed crossfades to a new score
rotateXnumber0 — degrees, -70–70, tips the top away
rotateYnumber0 — degrees, -70–70, swings the right away
rotateZnumber0 — degrees, spins the plane clockwise
theme"light" | "dark" | "auto""auto"
classNamestringReact only
classstringSvelte only

Omit color and theme="auto" picks phosphor green on dark, forest ink on light. The canvas is transparent in both themes, so it sits on whatever background the parent paints.