SvgVexFlowBackend.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import Vex = require("vexflow");
  2. import {VexFlowBackend} from "./VexFlowBackend";
  3. import {VexFlowConverter} from "./VexFlowConverter";
  4. import {FontStyles} from "../../../Common/Enums/FontStyles";
  5. import {Fonts} from "../../../Common/Enums/Fonts";
  6. import {RectangleF2D} from "../../../Common/DataObjects/RectangleF2D";
  7. import {PointF2D} from "../../../Common/DataObjects/PointF2D";
  8. import { EngravingRules } from "..";
  9. export class SvgVexFlowBackend extends VexFlowBackend {
  10. private ctx: Vex.Flow.SVGContext;
  11. public getBackendType(): number {
  12. return Vex.Flow.Renderer.Backends.SVG;
  13. }
  14. public initialize(container: HTMLElement): void {
  15. this.canvas = document.createElement("div");
  16. this.inner = this.canvas;
  17. this.inner.style.position = "relative";
  18. this.canvas.style.zIndex = "0";
  19. container.appendChild(this.inner);
  20. this.renderer = new Vex.Flow.Renderer(this.canvas, this.getBackendType());
  21. this.ctx = <Vex.Flow.SVGContext>this.renderer.getContext();
  22. }
  23. public getContext(): Vex.Flow.SVGContext {
  24. return this.ctx;
  25. }
  26. public clear(): void {
  27. if (!this.ctx) {
  28. return;
  29. }
  30. //const { svg } = this.ctx; // seems to make svg static between osmd instances.
  31. const svg: SVGElement = this.ctx.svg;
  32. // removes all children from the SVG element,
  33. // effectively clearing the SVG viewport
  34. while (svg.lastChild) {
  35. svg.removeChild(svg.lastChild);
  36. }
  37. }
  38. public scale(k: number): void {
  39. this.ctx.scale(k, k);
  40. }
  41. public translate(x: number, y: number): void {
  42. // TODO: implement this
  43. }
  44. public renderText(fontHeight: number, fontStyle: FontStyles, font: Fonts, text: string,
  45. heightInPixel: number, screenPosition: PointF2D, color: string = undefined): void {
  46. this.ctx.save();
  47. if (color) {
  48. this.ctx.attributes.fill = color;
  49. this.ctx.attributes.stroke = color;
  50. }
  51. this.ctx.setFont(EngravingRules.Rules.DefaultFontFamily, fontHeight, VexFlowConverter.fontStyle(fontStyle));
  52. // font size is set by VexFlow in `pt`. This overwrites the font so it's set to px instead
  53. this.ctx.attributes["font-size"] = `${fontHeight}px`;
  54. this.ctx.state["font-size"] = `${fontHeight}px`;
  55. this.ctx.fillText(text, screenPosition.x, screenPosition.y + heightInPixel);
  56. this.ctx.restore();
  57. }
  58. public renderRectangle(rectangle: RectangleF2D, styleId: number, alpha: number = 1): void {
  59. this.ctx.save();
  60. this.ctx.attributes.fill = VexFlowConverter.style(styleId);
  61. this.ctx.attributes["fill-opacity"] = alpha;
  62. this.ctx.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
  63. this.ctx.restore();
  64. this.ctx.attributes["fill-opacity"] = 1;
  65. }
  66. public renderLine(start: PointF2D, stop: PointF2D, color: string = "#FF0000FF", lineWidth: number = 2): void {
  67. this.ctx.save();
  68. this.ctx.beginPath();
  69. this.ctx.moveTo(start.x, start.y);
  70. this.ctx.lineTo(stop.x, stop.y);
  71. this.ctx.attributes.stroke = color;
  72. //this.ctx.attributes.strokeStyle = color;
  73. //this.ctx.attributes["font-weight"] = "bold";
  74. //this.ctx.attributes["stroke-linecap"] = "round";
  75. this.ctx.lineWidth = lineWidth;
  76. this.ctx.stroke();
  77. this.ctx.restore();
  78. }
  79. public renderCurve(points: PointF2D[]): void {
  80. this.ctx.beginPath();
  81. this.ctx.moveTo(points[0].x, points[0].y);
  82. this.ctx.bezierCurveTo(
  83. points[1].x,
  84. points[1].y,
  85. points[2].x,
  86. points[2].y,
  87. points[3].x,
  88. points[3].y
  89. );
  90. this.ctx.lineTo(points[7].x, points[7].y);
  91. this.ctx.bezierCurveTo(
  92. points[6].x,
  93. points[6].y,
  94. points[5].x,
  95. points[5].y,
  96. points[4].x,
  97. points[4].y
  98. );
  99. this.ctx.lineTo(points[0].x, points[0].y);
  100. //this.ctx.stroke();
  101. this.ctx.closePath();
  102. this.ctx.fill();
  103. }
  104. }