メインコンテンツまでスキップ

Piano

カスタマイズできるピアノのコンポーネント。

Source Style
Loading...
function App() {
  const synthRef = useRef<Tone.PolySynth | null>(null)

  useEffect(() => {
    const synth = new Tone.PolySynth({ volume: -6 }).toDestination()
    synthRef.current = synth

    return () => {
      synth.releaseAll()
      synth.dispose()
      if (synthRef.current === synth) synthRef.current = null
    }
  }, [])

  return (
    <div
      style={{
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
      }}
    >
      <Piano.Root
        className={pianoTheme.root}
        classes={{
          keyLabelWrapper: pianoTheme.keyLabelWrapper,
          keyLabel: pianoTheme.keyLabel,
        }}
        keyProps={(_note, { keyType }) => ({
          className:
            keyType === 'white' ? pianoTheme.whiteKey : pianoTheme.blackKey,
        })}
        noteRange={{ first: noteNumber('C3'), last: noteNumber('B4') }}
        keyboardShortcuts={SHORTCUTS.HOME_ROW}
        onPlayNote={(noteNumber) => {
          synthRef.current?.triggerAttack(noteName(noteNumber))
        }}
        onStopNote={(noteNumber) => {
          synthRef.current?.triggerRelease(noteName(noteNumber))
        }}
        label={(_, { index }) => SHORTCUTS.HOME_ROW.keys[index]?.toUpperCase()}
      />
    </div>
  )
}

インポート​

import { SHORTCUTS } from '@tremolo-ui/dom'
import { noteNumber, noteName } from '@tremolo-ui/functions'
import { Piano } from '@tremolo-ui/react'

API リファレンス​

Piano.Root は、下の props に加えて、描画する要素の属性(className や style など)も受け取ります。

Svelte / Vue でも props は同じで、書き方だけがそれぞれの流儀になります(className ではなく class、bind:value や v-model、中身は snippet やスロットなど)。Svelte と Vue を参照してください。

状態は data 属性として要素に乗っているので、セレクタ 1 つで届きます(スタイリングを参照)。属性はその状態が on の間だけ付きます。

Root​

noteRange のノートごとに鍵盤を描きます。他のパートは無く、鍵盤は label と keyProps でカスタマイズします。

Prop型既定値
classes{ keyLabelWrapper?: string; keyLabel?: string }—
noteRange*NoteRange—
glissandobooleantrue
midiMaxnumber127
keyboardShortcutsKeyboardShortcuts—
keyboardShortcutsScopeKeyboardShortcutsScope'root'
resizablebooleanfalse
whiteKeyWidthnumber40
keyGapnumber1
blackKeyWidthRationumber0.65
blackKeyHeightRationumber0.6
label(note: number, state: KeyState) => ReactNode—
keyProps(note: number, state: KeyState) => KeyAttributes—
onPlayNote(note: number, velocity?: number) => void—
onStopNote(note: number) => void—
actionsRefRef<PianoMethods>—

すべての説明: PianoProps

鍵盤の高さと各キーの色は CSS で指定します。キーごとにクラス、スタイル、 data-* 属性を付けるには keyProps を使います。

Data 属性値
[data-resizable]resizable のときに付きます

鍵盤​

各鍵盤が持つ属性です。

Data 属性値
[data-note]"0" … "127"
[data-note-key]"C" | "C#" | … | "B"
[data-active]ノートが鳴っている間に付きます
[data-disabled]ノートが midiMax より高いときに付きます

鍵盤には keyProps から属性を足せるので、自分で決めた状態も属性 1 つで表せます:

keyProps={(note) => ({ 'data-in-scale': inScale(note, 0, 'major') ? '' : undefined })}