Musical keyboard component written in React.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

47 lignes
1.5 KiB

  1. import isNaturalKey from './isNaturalKey'
  2. import groupKeysIntoOctaves from './groupKeysIntoOctaves'
  3. import getOctaveCompleteness from './getOctaveCompleteness'
  4. import getOctaveCount from './getOctaveCount'
  5. import generateKeys from './generateKeys'
  6. interface GetKeyWidth {
  7. (k: number): number,
  8. }
  9. interface GetKeyWidthDecorator {
  10. (startKey: number, endKey: number): GetKeyWidth,
  11. }
  12. const ACCIDENTAL_KEY_TO_NATURAL_KEY_WIDTH_RATIO = 18 / 36
  13. const getKeyWidthDecorator: GetKeyWidthDecorator = (startKey, endKey): GetKeyWidth => (k) => {
  14. const dummyKeys = generateKeys(startKey, endKey)
  15. const keysGroupedIntoOctaves = groupKeysIntoOctaves(dummyKeys)
  16. const octaveCompleteness = Object
  17. .entries(keysGroupedIntoOctaves)
  18. .map<number[]>(([octave, keys]) => [
  19. octave as unknown as number,
  20. keys[0],
  21. keys.slice(-1)[0],
  22. ])
  23. .reduce<Record<number, number>>(
  24. (theOctaveCompleteness, [octave, firstKey, lastKey]) => ({
  25. ...theOctaveCompleteness,
  26. [octave]: getOctaveCompleteness(firstKey, lastKey),
  27. }),
  28. {}
  29. )
  30. const fractionalOctaveCount = Object
  31. .values(octaveCompleteness)
  32. .reduce(
  33. (a, b) => a + b,
  34. 0
  35. )
  36. const octaveCount = getOctaveCount(startKey, endKey)
  37. const naturalKeyWidth = 100 * (octaveCount / fractionalOctaveCount) / (octaveCount * 7)
  38. return isNaturalKey(k) ? naturalKeyWidth : naturalKeyWidth * ACCIDENTAL_KEY_TO_NATURAL_KEY_WIDTH_RATIO // naturalKeyWidth * 13.7 / 23.5}
  39. }
  40. export default getKeyWidthDecorator