lit-sheet-music

安装量: 35
排名: #19825

安装

npx skills add https://github.com/rodydavis/skills --skill lit-sheet-music

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:

Lit Sheet Music

If local musicxml is intended to be used update index.html with the following:

Lit Sheet Music

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 { // Check if src attribute is set and prefer it over the slot if (this.src.length > 0) return fetch(this.src).then((res) => res.text()); // Check if slot children exist and return the xml const elem = this.parentElement?.querySelector( 'script[type="text/xml"]' ) as HTMLScriptElement; if (elem) return elem.innerHTML; // Return nothing if neither is found return ""; } async firstUpdated() { this.controller = new OpenSheetMusicDisplay(this.canvas, this.options); this.requestUpdate(); // Check for any music and update if found const music = await this.getMusic(); if (music.length > 0) this.renderMusic(music); } } declare global { interface HTMLElementTagNameMap { "sheet-music": SheetMusic; } } Run npm run dev and the following should appear if all went well: Conclusion If you want to learn more about building with Lit you can read the docs here . The source for this example can be found here .

返回排行榜