VexFlowGraphicalNote.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import Vex from "vexflow";
  2. import {GraphicalNote} from "../GraphicalNote";
  3. import {Note} from "../../VoiceData/Note";
  4. import {ClefInstruction} from "../../VoiceData/Instructions/ClefInstruction";
  5. import {VexFlowConverter} from "./VexFlowConverter";
  6. import {Pitch} from "../../../Common/DataObjects/Pitch";
  7. import {Fraction} from "../../../Common/DataObjects/Fraction";
  8. import {OctaveEnum, OctaveShift} from "../../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
  9. import { GraphicalVoiceEntry } from "../GraphicalVoiceEntry";
  10. import { KeyInstruction } from "../../VoiceData/Instructions/KeyInstruction";
  11. /**
  12. * The VexFlow version of a [[GraphicalNote]].
  13. */
  14. export class VexFlowGraphicalNote extends GraphicalNote {
  15. constructor(note: Note, parent: GraphicalVoiceEntry, activeClef: ClefInstruction,
  16. octaveShift: OctaveEnum = OctaveEnum.NONE, graphicalNoteLength: Fraction = undefined) {
  17. super(note, parent, graphicalNoteLength);
  18. this.clef = activeClef;
  19. this.octaveShift = octaveShift;
  20. if (note.Pitch) {
  21. // TODO: Maybe shift to Transpose function when available
  22. const drawPitch: Pitch = note.isRest() ? note.Pitch : OctaveShift.getPitchFromOctaveShift(note.Pitch, octaveShift);
  23. this.vfpitch = VexFlowConverter.pitch(this, drawPitch);
  24. this.vfpitch[1] = undefined;
  25. }
  26. }
  27. public octaveShift: OctaveEnum;
  28. // The pitch of this note as given by VexFlowConverter.pitch
  29. public vfpitch: [string, string, ClefInstruction];
  30. // The corresponding VexFlow StaveNote (plus its index in the chord)
  31. public vfnote: [Vex.Flow.StemmableNote, number];
  32. // The current clef
  33. private clef: ClefInstruction;
  34. /**
  35. * Update the pitch of this note. Necessary in order to display accidentals correctly.
  36. * This is called by VexFlowGraphicalSymbolFactory.addGraphicalAccidental.
  37. * @param pitch
  38. */
  39. public setAccidental(pitch: Pitch): void {
  40. // if (this.vfnote) {
  41. // let pitchAcc: AccidentalEnum = pitch.Accidental;
  42. // const acc: string = Pitch.accidentalVexflow(pitch.Accidental);
  43. // if (acc) {
  44. // alert(acc);
  45. // this.vfnote[0].addAccidental(this.vfnote[1], new Vex.Flow.Accidental(acc));
  46. // }
  47. // } else {
  48. // revert octave shift, as the placement of the note is independent of octave brackets
  49. const drawPitch: Pitch = OctaveShift.getPitchFromOctaveShift(pitch, this.octaveShift);
  50. // recalculate the pitch, and this time don't ignore the accidental:
  51. this.vfpitch = VexFlowConverter.pitch(this, drawPitch);
  52. //}
  53. }
  54. public Transpose(keyInstruction: KeyInstruction, activeClef: ClefInstruction, halfTones: number, octaveEnum: OctaveEnum): Pitch {
  55. const tranposedPitch: Pitch = super.Transpose(keyInstruction, activeClef, halfTones, octaveEnum);
  56. const drawPitch: Pitch = OctaveShift.getPitchFromOctaveShift(tranposedPitch, this.octaveShift);
  57. this.vfpitch = VexFlowConverter.pitch(this, drawPitch);
  58. this.vfpitch[1] = undefined;
  59. return drawPitch;
  60. }
  61. /**
  62. * Set the VexFlow StaveNote corresponding to this GraphicalNote, together with its index in the chord.
  63. * @param note
  64. * @param index
  65. */
  66. public setIndex(note: Vex.Flow.StemmableNote, index: number): void {
  67. this.vfnote = [note, index];
  68. }
  69. /**
  70. * Gets the clef for this note
  71. */
  72. public Clef(): ClefInstruction {
  73. return this.clef;
  74. }
  75. /**
  76. * Gets the id of the SVGGElement containing this note, given the SVGRenderer is used.
  77. * This is for low-level rendering hacks and should be used with caution.
  78. */
  79. public getSVGId(): string {
  80. return this.vfnote[0].getAttribute("id");
  81. }
  82. /**
  83. * Gets the SVGGElement containing this note, given the SVGRenderer is used.
  84. * This is for low-level rendering hacks and should be used with caution.
  85. */
  86. public getSVGGElement(): SVGGElement {
  87. return this.vfnote[0].getAttribute("el");
  88. }
  89. }