VexFlowBackend.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import Vex from "vexflow";
  2. import {FontStyles} from "../../../Common/Enums/FontStyles";
  3. import {Fonts} from "../../../Common/Enums/Fonts";
  4. import {RectangleF2D} from "../../../Common/DataObjects/RectangleF2D";
  5. import {PointF2D} from "../../../Common/DataObjects/PointF2D";
  6. import {GraphicalMusicPage, EngravingRules} from "..";
  7. import {BackendType} from "../../../OpenSheetMusicDisplay";
  8. export class VexFlowBackends {
  9. public static CANVAS: 0;
  10. public static RAPHAEL: 1; // this is currently unused in OSMD, and outdated in Vexflow.
  11. // maybe SVG should be 1? but this could be a breaking change if people use numbers (2) instead of names (.SVG).
  12. public static SVG: 2;
  13. public static VML: 3; // this is currently unused in OSMD, and outdated in Vexflow
  14. }
  15. export abstract class VexFlowBackend {
  16. /** The GraphicalMusicPage the backend is drawing from. Each backend only renders one GraphicalMusicPage, to which the coordinates are relative. */
  17. public graphicalMusicPage: GraphicalMusicPage;
  18. protected rules: EngravingRules;
  19. public abstract initialize(container: HTMLElement): void;
  20. public getInnerElement(): HTMLElement {
  21. return this.inner;
  22. }
  23. public getCanvas(): HTMLElement {
  24. return this.canvas;
  25. }
  26. public getRenderElement(): HTMLElement {
  27. //console.log("backend type: " + this.getVexflowBackendType());
  28. let renderingHtmlElement: HTMLElement = this.canvas; // for SVGBackend
  29. if (this.getVexflowBackendType() === Vex.Flow.Renderer.Backends.CANVAS) {
  30. renderingHtmlElement = this.inner;
  31. // usage in removeFromContainer:
  32. // for SVG, this.canvas === this.inner, but for Canvas, removing this.canvas causes an error because it's not a child of container,
  33. // so we have to remove this.inner instead.
  34. }
  35. return renderingHtmlElement;
  36. }
  37. public getRenderer(): Vex.Flow.Renderer {
  38. return this.renderer;
  39. }
  40. public removeAllChildrenFromContainer(container: HTMLElement): void {
  41. while (container.children.length !== 0) {
  42. container.removeChild(container.children.item(0));
  43. }
  44. }
  45. // note: removing single children to remove all is error-prone, because sometimes a random SVG-child remains.
  46. public removeFromContainer(container: HTMLElement): void {
  47. const htmlElementToRemove: HTMLElement = this.getRenderElement();
  48. // only remove child if the container has this child, otherwise it will throw an error.
  49. for (let i: number = 0; i < container.children.length; i++) {
  50. if (container.children.item(i) === htmlElementToRemove) {
  51. container.removeChild(htmlElementToRemove);
  52. break;
  53. }
  54. }
  55. // there is unfortunately no built-in container.hasChild(child) method.
  56. }
  57. public abstract getContext(): Vex.IRenderContext;
  58. // public abstract setWidth(width: number): void;
  59. // public abstract setHeight(height: number): void;
  60. public abstract scale(k: number): void;
  61. public resize(x: number, y: number): void {
  62. this.renderer.resize(x, y);
  63. }
  64. public abstract clear(): void;
  65. public abstract translate(x: number, y: number): void;
  66. public abstract renderText(fontHeight: number, fontStyle: FontStyles, font: Fonts, text: string,
  67. heightInPixel: number, screenPosition: PointF2D, color?: string): void;
  68. /**
  69. * Renders a rectangle with the given style to the screen.
  70. * It is given in screen coordinates.
  71. * @param rectangle the rect in screen coordinates
  72. * @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.
  73. * @param styleId the style id
  74. * @param alpha alpha value between 0 and 1
  75. */
  76. public abstract renderRectangle(rectangle: RectangleF2D, styleId: number, alpha: number): void;
  77. public abstract renderLine(start: PointF2D, stop: PointF2D, color: string, lineWidth: number): void;
  78. public abstract renderCurve(points: PointF2D[]): void;
  79. public abstract getVexflowBackendType(): Vex.Flow.Renderer.Backends;
  80. /** The general type of backend: Canvas or SVG.
  81. * This is not used for now (only VexflowBackendType used), but it may be useful when we don't want to use a Vexflow class.
  82. */
  83. public abstract getOSMDBackendType(): BackendType;
  84. protected renderer: Vex.Flow.Renderer;
  85. protected inner: HTMLElement;
  86. protected canvas: HTMLElement;
  87. }