Musical keyboard component written in React.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 4 години
преди 4 години
преди 4 години
преди 4 години
преди 4 години
преди 4 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import * as React from 'react'
  2. import SoundGenerator from '../services/SoundGenerator'
  3. type ChangeProps = {
  4. setChannel(channel: number): void
  5. }
  6. type Change = (props: ChangeProps) => React.ChangeEventHandler<HTMLInputElement>
  7. export const change: Change = ({ setChannel }) => e => {
  8. const { value: rawValue } = e.target
  9. const value = Number(rawValue)
  10. setChannel(value)
  11. }
  12. type KeyChannel = {
  13. key: number,
  14. velocity: number,
  15. channel: number,
  16. }
  17. type KeyChannelCallback = (oldKeys: KeyChannel[]) => KeyChannel[]
  18. type HandleProps = {
  19. setKeyChannels(callback: KeyChannelCallback | KeyChannel[]): void,
  20. generator?: SoundGenerator,
  21. channel: number,
  22. }
  23. type Handle = (props: HandleProps) => (newKeys: KeyChannel[]) => void
  24. export const handle: Handle = ({ setKeyChannels, generator, channel, }) => newKeys => {
  25. setKeyChannels((oldKeys) => {
  26. if (generator! !== undefined) {
  27. const oldKeysKeys = oldKeys.map((k) => k.key)
  28. const newKeysKeys = newKeys.map((k) => k.key)
  29. const keysOff = oldKeys.filter((ok) => !newKeysKeys.includes(ok.key))
  30. const keysOn = newKeys.filter((nk) => !oldKeysKeys.includes(nk.key))
  31. keysOn.forEach((k) => {
  32. generator.noteOn(channel, k.key, Math.floor(k.velocity * 127))
  33. })
  34. keysOff.forEach((k) => {
  35. generator.noteOff(channel, k.key, Math.floor(k.velocity * 127))
  36. })
  37. }
  38. return newKeys
  39. })
  40. }