Pitch Class Clock
pitch-class-clockVisualizersChords as shapes on a twelve-note dial.
$ pnpm dlx shadcn@latest add @pluginui/core-pitch-class-clockInstall
Copies the source into your project. Anything it depends on comes with it. Run this in your React project with shadcn initialized; no registry configuration is needed.
Pulls in
Install using the registry URL
$ pnpm dlx shadcn@latest add https://pluginui.com/r/core-pitch-class-clock.jsonUsage
Connect the documented props to your application or host.
import { PitchClassClock } from "@/components/ui/pitch-class-clock"
// MIDI numbers or pitch classes; both reduce mod 12.
<PitchClassClock notes={[60, 64, 67]} sequence="fifths" chordShape="polygon" />About Pitch Class Clock
Collapsing pitch to pitch class removes octave and voicing, leaving the information that names a chord. Drawn on a ring, a chord becomes a polygon and the polygon is a fingerprint: every major triad is the same triangle at a different rotation, every minor triad its mirror, and a diminished seventh a perfect square. Transposition rotates the shape; changing quality changes it. Choose the ring order to decide which chords look simple. Chromatic order spaces notes by semitone, making scales arcs; fifths order clusters diatonic material so triads open out. Nodes remain equidistant in every ordering, keeping shapes comparable.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| notes | number[] | [] | The sounding notes, as MIDI numbers or pitch classes. Reduced mod 12 and deduped, so [60, 64, 67] and [0, 4, 7] light the same nodes. |
| sequence | "chromatic" | "fifths" | "+2" | "chromatic" | Ring ordering: by semitone, by fifth, or by whole tone. Note that +2 is not coprime with 12, so that dial shows each whole-tone class twice. |
| chordShape | "polygon" | "lines" | "none" | "polygon" | How the sounding notes are joined: a filled polygon, an open path, or not at all. |
| size | number | 220 | Overall square size in pixels. |
| nodeRadius | number | 14 | Radius of each note node; also the ring's inset from the edge. |
| startAtTop | boolean | true | Put ring index 0 at twelve o'clock. False puts it at three o'clock. |
| showLabels | boolean | true | Draw the note name inside each node. |
| color | string | — | Highlight and connector colour. Defaults to the --uikit-accent token. |
Interaction
- Drag with pointer capture, so the gesture keeps tracking past the edge of the control.
- Shift while dragging for a fine pass; release it mid-gesture and coarse tracking resumes.
- Double-click resets to
defaultValue. - Arrow keys step normally, Shift+arrow steps finely, PageUp/PageDown jump by ten, Home/End go to the extremes.
- Proper
sliderandswitchroles with livearia-valuetext, so a screen reader announces the formatted value rather than the raw number. - The scroll wheel adjusts the value while the pointer is over the control; stepped ranges move at least one declared step per notch by default.