@norarcasey/pianora
v0.1.0
Published
An embeddable React piano — play with mouse, touch, or your computer keyboard, record a melody, and play it back. Powered by Tone.js.
Downloads
95
Maintainers
Readme
Pianora 🎹
An embeddable React + TypeScript piano. Play with your mouse, a touch screen, or your computer keyboard — every note you play is recorded, and you can play it back (or play the built-in "Axel F" demo song until you've recorded something). Sound is powered by Tone.js.
Built with Vite and tested with Vitest + React Testing Library.
This is a modern Vite/React/TypeScript port of an earlier Create React App project.
Quick start
npm install
npm run dev # demo site at http://localhost:5173
npm test # run the test suite
npm run build # build the demo site for deployment
npm run build:lib # build the embeddable component libraryEmbedding the component
import { Pianora } from '@norarcasey/pianora'
import '@norarcasey/pianora/style.css'
export function App() {
return <Pianora />
}tone is a dependency and installs automatically; react / react-dom are
peer dependencies you already have.
Props
| Prop | Type | Default | Description |
| ------------------------ | --------------------- | ----------- | -------------------------------------------------------------------- |
| initialOctave | number | 4 | Starting octave for the lowest C. |
| minOctave | number | 1 | Lowest selectable octave. |
| maxOctave | number | 6 | Highest selectable octave. |
| demoSong | PlaybackNote[] | AXEL_F | Melody played when nothing has been recorded yet. |
| enableComputerKeyboard | boolean | true | Let the physical keyboard (a w s e d …) play notes. |
| showRecorder | boolean | true | Show the playback display, transport controls, and octave stepper. |
| title | string \| null | "Pianora" | Heading above the piano; pass null to hide it. |
| className | string | — | Extra class on the root element. |
Just the keyboard
<Pianora title={null} showRecorder={false} enableComputerKeyboard={false} />How it works
src/piano/notes.ts— the framework-free keyboard layout: which keys exist, their colors, computer-keyboard bindings, andnoteForKey()to resolve a key + octave into a sounding note likeC4. Fully unit-tested.src/piano/usePianora.ts— a React hook that owns all audio + recording state. It lazily creates a Tone.jsPolySynthon the first user gesture (so it never touches the audio context at mount), captures press/release timing into playback notes, and drives playback through aTone.Parton the transport.src/piano/axel-f.ts— the default demo melody, in the shapeTone.Partconsumes.src/components/Pianora.tsx— composes the keyboard, playback display, transport controls, and octave stepper. Keys use Pointer Events so mouse, touch, and pen all work from one code path.
Playing with the computer keyboard
The bottom row maps to white keys and the row above to the black keys, just like a real layout:
white: a s d f g h j k l ;
black: w e t y u i oNotes on the port
The original used Create React App, React 16, FontAwesome, rc-input-number,
react-device-detect, and Tone.js v13. This port drops all of those: Vite +
React 18, inline SVG icons, a native octave stepper, unified Pointer Events, and
Tone.js v15 (toDestination(), getTransport()). The two React contexts were
consolidated into the single usePianora hook.
