GraphicalNote.ts 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import {Note} from "../VoiceData/Note";
  2. import {Fraction} from "../../Common/DataObjects/Fraction";
  3. import {KeyInstruction} from "../VoiceData/Instructions/KeyInstruction";
  4. import {ClefInstruction} from "../VoiceData/Instructions/ClefInstruction";
  5. import {OctaveEnum} from "../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
  6. import {Pitch} from "../../Common/DataObjects/Pitch";
  7. import {GraphicalStaffEntry} from "./GraphicalStaffEntry";
  8. import {GraphicalObject} from "./GraphicalObject";
  9. import {MusicSheetCalculator} from "./MusicSheetCalculator";
  10. import {BoundingBox} from "./BoundingBox";
  11. /**
  12. * The graphical counterpart of a [[Note]]
  13. */
  14. export class GraphicalNote extends GraphicalObject {
  15. constructor(note: Note, parent: GraphicalStaffEntry, graphicalNoteLength: Fraction = undefined) {
  16. super();
  17. this.sourceNote = note;
  18. this.parentStaffEntry = parent;
  19. this.PositionAndShape = new BoundingBox(this, parent.PositionAndShape);
  20. if (graphicalNoteLength !== undefined) {
  21. this.graphicalNoteLength = graphicalNoteLength;
  22. } else {
  23. if (note.NoteTie !== undefined) {
  24. this.graphicalNoteLength = note.calculateNoteLengthWithoutTie();
  25. } else {
  26. this.graphicalNoteLength = note.Length;
  27. }
  28. }
  29. this.numberOfDots = this.calculateNumberOfNeededDots(this.graphicalNoteLength);
  30. }
  31. public sourceNote: Note;
  32. public graphicalNoteLength: Fraction;
  33. public parentStaffEntry: GraphicalStaffEntry;
  34. public numberOfDots: number;
  35. public get ParentList(): GraphicalNote[] {
  36. for (let idx: number = 0, len: number = this.parentStaffEntry.notes.length; idx < len; ++idx) {
  37. const graphicalNotes: GraphicalNote[] = this.parentStaffEntry.notes[idx];
  38. if (graphicalNotes.indexOf(this) !== -1) {
  39. return graphicalNotes;
  40. }
  41. }
  42. return undefined;
  43. }
  44. public Transpose(keyInstruction: KeyInstruction, activeClef: ClefInstruction, halfTones: number, octaveEnum: OctaveEnum): Pitch {
  45. let transposedPitch: Pitch = this.sourceNote.Pitch;
  46. if (MusicSheetCalculator.transposeCalculator !== undefined) {
  47. transposedPitch = MusicSheetCalculator.transposeCalculator.transposePitch(this.sourceNote.Pitch, keyInstruction, halfTones);
  48. }
  49. return transposedPitch;
  50. }
  51. /**
  52. * Return the number of dots needed to represent the given fraction.
  53. * @param fraction
  54. * @returns {number}
  55. */
  56. private calculateNumberOfNeededDots(fraction: Fraction): number {
  57. let num: number = 1;
  58. let product: number = 2;
  59. const expandedNumerator: number = fraction.GetExpandedNumerator();
  60. if (this.sourceNote === undefined || this.sourceNote.NoteTuplet === undefined) {
  61. while (product < expandedNumerator) {
  62. num++;
  63. product = <number>Math.pow(2, num);
  64. }
  65. }
  66. return Math.min(3, num - 1);
  67. }
  68. }