VexFlowInstrumentBracket.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import Vex from "vexflow";
  2. import { GraphicalObject } from "../GraphicalObject";
  3. import { VexFlowStaffLine } from "./VexFlowStaffLine";
  4. import { BoundingBox } from "../BoundingBox";
  5. import { VexFlowMeasure } from "./VexFlowMeasure";
  6. import { unitInPixels } from "./VexFlowMusicSheetDrawer";
  7. /**
  8. * Class that defines a instrument bracket at the beginning of a line.
  9. */
  10. export class VexFlowInstrumentBracket extends GraphicalObject {
  11. public vexflowConnector: Vex.Flow.StaveConnector;
  12. public Visible: boolean = true;
  13. constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine, depth: number = 0) {
  14. super();
  15. this.PositionAndShape = new BoundingBox(this, firstVexFlowStaffLine.ParentMusicSystem.PositionAndShape);
  16. const firstVexMeasure: VexFlowMeasure = firstVexFlowStaffLine.Measures[0] as VexFlowMeasure;
  17. const lastVexMeasure: VexFlowMeasure = lastVexFlowStaffLine.Measures[0] as VexFlowMeasure;
  18. this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), Vex.Flow.StaveConnector.type.BRACKET, depth);
  19. }
  20. /**
  21. * Render the bracket using the given backend
  22. * @param ctx Render Vexflow context
  23. */
  24. public draw(ctx: Vex.IRenderContext): void {
  25. // Draw vexflow brace. This sets the positions inside the connector.
  26. if (this.Visible) {
  27. this.vexflowConnector.setContext(ctx).draw();
  28. }
  29. // Set bounding box
  30. const con: Vex.Flow.StaveConnector = this.vexflowConnector;
  31. // First line in first stave
  32. const topY: number = con.top_stave.getYForLine(0);
  33. // Last line in last stave
  34. const botY: number = con.bottom_stave.getYForLine(con.bottom_stave.getNumLines() - 1) + con.thickness;
  35. // Set bounding box position and size in OSMD units
  36. this.PositionAndShape.AbsolutePosition.x = (con.top_stave.getX() - 2 + con.x_shift) / unitInPixels;
  37. this.PositionAndShape.AbsolutePosition.y = topY / unitInPixels;
  38. this.PositionAndShape.Size.height = (botY - topY) / unitInPixels;
  39. this.PositionAndShape.Size.width = 12 / unitInPixels; // width is always 12 -> vexflow implementation
  40. }
  41. /**
  42. * Adds a connector between two staves
  43. *
  44. * @param {Stave} stave1: First stave
  45. * @param {Stave} stave2: Second stave
  46. * @param {Flow.StaveConnector.type} type: Type of connector
  47. */
  48. private addConnector(stave1: Vex.Flow.Stave, stave2: Vex.Flow.Stave, type: any, depth: number): void {
  49. this.vexflowConnector = new Vex.Flow.StaveConnector(stave1, stave2)
  50. .setType(type)
  51. .setXShift(depth * -5);
  52. }
  53. }