VexFlowMusicSheetDrawer.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import {MusicSheetDrawer} from "../MusicSheetDrawer";
  2. import {RectangleF2D} from "../../../Common/DataObjects/RectangleF2D";
  3. import {VexFlowMeasure} from "./VexFlowMeasure";
  4. import {PointF2D} from "../../../Common/DataObjects/PointF2D";
  5. import {GraphicalLabel} from "../GraphicalLabel";
  6. import {VexFlowTextMeasurer} from "./VexFlowTextMeasurer";
  7. import {MusicSystem} from "../MusicSystem";
  8. import {GraphicalObject} from "../GraphicalObject";
  9. import {GraphicalLayers} from "../DrawingEnums";
  10. import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
  11. import {VexFlowBackend} from "./VexFlowBackend";
  12. import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
  13. /**
  14. * This is a global constant which denotes the height in pixels of the space between two lines of the stave
  15. * (when zoom = 1.0)
  16. * @type number
  17. */
  18. export const unitInPixels: number = 10;
  19. export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
  20. private backend: VexFlowBackend;
  21. private zoom: number = 1.0;
  22. constructor(element: HTMLElement,
  23. backend: VexFlowBackend,
  24. isPreviewImageDrawer: boolean = false) {
  25. super(new VexFlowTextMeasurer(), isPreviewImageDrawer);
  26. this.backend = backend;
  27. }
  28. public clear(): void {
  29. this.backend.clear();
  30. }
  31. /**
  32. * Zoom the rendering areas
  33. * @param k is the zoom factor
  34. */
  35. public scale(k: number): void {
  36. this.zoom = k;
  37. this.backend.scale(this.zoom);
  38. }
  39. /**
  40. * Resize the rendering areas
  41. * @param x
  42. * @param y
  43. */
  44. public resize(x: number, y: number): void {
  45. this.backend.resize(x, y);
  46. }
  47. public translate(x: number, y: number): void {
  48. this.backend.translate(x, y);
  49. }
  50. /**
  51. * Converts a distance from unit to pixel space.
  52. * @param unitDistance the distance in units
  53. * @returns {number} the distance in pixels
  54. */
  55. public calculatePixelDistance(unitDistance: number): number {
  56. return unitDistance * unitInPixels;
  57. }
  58. protected drawMeasure(measure: VexFlowMeasure): void {
  59. measure.setAbsoluteCoordinates(
  60. measure.PositionAndShape.AbsolutePosition.x * unitInPixels,
  61. measure.PositionAndShape.AbsolutePosition.y * unitInPixels
  62. );
  63. measure.draw(this.backend.getContext());
  64. // Draw the StaffEntries
  65. for (let staffEntry of measure.staffEntries) {
  66. this.drawStaffEntry(staffEntry);
  67. }
  68. }
  69. private drawStaffEntry(staffEntry: GraphicalStaffEntry): void {
  70. // Draw ChordSymbol
  71. if (staffEntry.graphicalChordContainer !== undefined) {
  72. this.drawLabel(staffEntry.graphicalChordContainer.GetGraphicalLabel, <number>GraphicalLayers.Notes);
  73. }
  74. }
  75. protected drawInstrumentBrace(brace: GraphicalObject, system: MusicSystem): void {
  76. // Draw InstrumentBrackets at beginning of line
  77. const vexBrace: VexFlowInstrumentBracket = (brace as VexFlowInstrumentBracket);
  78. vexBrace.draw(this.backend.getContext());
  79. }
  80. protected drawGroupBracket(bracket: GraphicalObject, system: MusicSystem): void {
  81. // empty
  82. }
  83. /**
  84. * Renders a Label to the screen (e.g. Title, composer..)
  85. * @param graphicalLabel holds the label string, the text height in units and the font parameters
  86. * @param layer is the current rendering layer. There are many layers on top of each other to which can be rendered. Not needed for now.
  87. * @param bitmapWidth Not needed for now.
  88. * @param bitmapHeight Not needed for now.
  89. * @param heightInPixel the height of the text in screen coordinates
  90. * @param screenPosition the position of the lower left corner of the text in screen coordinates
  91. */
  92. protected renderLabel(graphicalLabel: GraphicalLabel, layer: number, bitmapWidth: number,
  93. bitmapHeight: number, heightInPixel: number, screenPosition: PointF2D): void {
  94. const height: number = graphicalLabel.Label.fontHeight * unitInPixels;
  95. const { fontStyle, font, text } = graphicalLabel.Label;
  96. this.backend.renderText(height, fontStyle, font, text, heightInPixel, screenPosition);
  97. }
  98. /**
  99. * Renders a rectangle with the given style to the screen.
  100. * It is given in screen coordinates.
  101. * @param rectangle the rect in screen coordinates
  102. * @param layer is the current rendering layer. There are many layers on top of each other to which can be rendered. Not needed for now.
  103. * @param styleId the style id
  104. */
  105. protected renderRectangle(rectangle: RectangleF2D, layer: number, styleId: number): void {
  106. this.backend.renderRectangle(rectangle, styleId);
  107. }
  108. /**
  109. * Converts a point from unit to pixel space.
  110. * @param point
  111. * @returns {PointF2D}
  112. */
  113. protected applyScreenTransformation(point: PointF2D): PointF2D {
  114. return new PointF2D(point.x * unitInPixels, point.y * unitInPixels);
  115. }
  116. /**
  117. * Converts a rectangle from unit to pixel space.
  118. * @param rectangle
  119. * @returns {RectangleF2D}
  120. */
  121. protected applyScreenTransformationForRect(rectangle: RectangleF2D): RectangleF2D {
  122. return new RectangleF2D(rectangle.x * unitInPixels, rectangle.y * unitInPixels, rectangle.width * unitInPixels, rectangle.height * unitInPixels);
  123. }
  124. }