Musical keyboard component written in React.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

50 řádky
1.6 KiB

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