Lit Sheet Music In this article I will go over how to set up a Lit web component and use it to render musicxml from a src attribute or inline xml using opensheetmusicdisplay . Now any sheet music can be rendered based on the browser width as an svg or canvas (and will resize when the viewport changes). TLDR The final source here and an online demo . Prerequisites Vscode Node >= 16 Typescript Getting Started We can start off by navigating in terminal to the location of the project and run the following: npm init @vitejs/app --template lit-ts Then enter a project name lit-sheet-music and now open the project in vscode and install the dependencies: cd lit-sheet-music npm i lit opensheetmusicdisplay npm i -D @types/node code . Update the vite.config.ts with the following: import { defineConfig } from "vite"; import { resolve } from "path"; export default defineConfig({ base: "/lit-sheet-music/", build: { lib: { entry: "src/lit-sheet-music.ts", formats: ["es"], }, rollupOptions: { input: { main: resolve(__dirname, "index.html"), }, }, }, }); Template Open up the index.html and update it with the following:
If local musicxml is intended to be used update index.html with the following:
We are passing a src attribute to the web component for this example but we can also add a script tag with the type attribute set to
text/xml
with the contents containing the json.
Web Component
Before we update our component we need to rename
my-element.ts
to
sheet-music.ts
Open up
sheet-music.ts
and update it with the following:
import { html, css, LitElement } from "lit";
import { customElement, property, query } from "lit/decorators.js";
import { IOSMDOptions, OpenSheetMusicDisplay } from "opensheetmusicdisplay";
type BackendType = "svg" | "canvas";
type DrawingType = "compact" | "default";
@customElement("sheet-music")
export class SheetMusic extends LitElement {
_zoom = 1.0;
@property({ type: Boolean }) allowDrop = false;
@property() src = "";
@query("main") canvas!: HTMLElement;
controller?: OpenSheetMusicDisplay;
options: IOSMDOptions = {
autoResize: true,
backend: "canvas" as BackendType,
drawingParameters: "default" as DrawingType,
};
static styles = cssmain {
overflow-x: auto;
};
render() {
return html<main></main>;
}
async renderMusic(content: string) {
if (!this.controller) return;
await this.controller.load(content);
this.controller.zoom = this._zoom;
this.controller.render();
this.requestUpdate();
}
private async getMusic(): Promise