浏览代码

fix(Cursor): fix cursor undefined for canvas backend, improve cursor creation (#736)

osmd.enableOrDisableCursor() used backend.getInnerElement(), which doesn't return the right element for CanvasBackend.
So now there's a new method getRenderElement(), which returns the right element depending on backend.

This was already used implicitly in VexFlowBackend.removeFromContainer(), which had the same issue,
but is now refactored into a method.

Also, cursor creation in osmd.enableOrDisableCursor() is refactored and improved to have more null checks.

npm test and npm run test:visual pass.

fix #736
sschmid 5 年之前
父节点
当前提交
cb193d2270

+ 13 - 7
src/MusicalScore/Graphical/VexFlow/VexFlowBackend.ts

@@ -30,6 +30,18 @@ export abstract class VexFlowBackend {
     return this.canvas;
   }
 
+  public getRenderElement(): HTMLElement {
+    //console.log("backend type: " + this.getVexflowBackendType());
+    let renderingHtmlElement: HTMLElement = this.canvas; // for SVGBackend
+    if (this.getVexflowBackendType() === Vex.Flow.Renderer.Backends.CANVAS) {
+      renderingHtmlElement = this.inner;
+      // usage in removeFromContainer:
+      // for SVG, this.canvas === this.inner, but for Canvas, removing this.canvas causes an error because it's not a child of container,
+      // so we have to remove this.inner instead.
+    }
+    return renderingHtmlElement;
+  }
+
   public getRenderer(): Vex.Flow.Renderer {
     return this.renderer;
   }
@@ -42,13 +54,7 @@ export abstract class VexFlowBackend {
 
   // note: removing single children to remove all is error-prone, because sometimes a random SVG-child remains.
   public removeFromContainer(container: HTMLElement): void {
-    //console.log("backend type: " + this.getVexflowBackendType());
-    let htmlElementToRemove: HTMLElement = this.canvas; // for SVGBackend
-    if (this.getVexflowBackendType() === Vex.Flow.Renderer.Backends.CANVAS) {
-      htmlElementToRemove = this.inner;
-      // for SVG, this.canvas === this.inner, but for Canvas, removing this.canvas causes an error because it's not a child of container,
-      // so we have to remove this.inner instead.
-    }
+    const htmlElementToRemove: HTMLElement = this.getRenderElement();
 
     // only remove child if the container has this child, otherwise it will throw an error.
     for (let i: number = 0; i < container.children.length; i++) {

+ 4 - 2
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -686,8 +686,10 @@ export class OpenSheetMusicDisplay {
             const previousIterator: MusicPartManagerIterator = this.cursor?.Iterator;
 
             // create new cursor
-            this.cursor = new Cursor(this.drawer.Backends[0].getInnerElement(), this);
-            if (this.sheet && this.graphic) { // else init is called in load()
+            if (this.drawer?.Backends?.length >= 1) {
+                this.cursor = new Cursor(this.drawer.Backends[0].getRenderElement(), this);
+            }
+            if (this.sheet && this.graphic && this.cursor) { // else init is called in load()
                 this.cursor.init(this.sheet.MusicPartManager, this.graphic);
             }