Getting Started with Vite + Typescript
I began looking into general web rendering, specifically looking at Obsidian and music notation.
Note that web languages are not my primary development environment, so the burst of frameworks, package managers and tooling is often difficult to keep up to date with. Also, it’s been a long time since I’ve done any custom controls, so I thought I’d dive in again.
General Notes
Mermaid is an MIT licensed javascript package (https://github.com/mermaid-js/mermaid/tree/develop) built in typescript and javascript.
- It uses d3 under the hood for at least some or maybe all rendering parts.
abcjs is a MIT javascript library for rendering music notation (https://github.com/paulrosen/abcjs/tree/main)
Part 1 - Basics
Getting Started
npm create vite@latest
Need to install the following packages:
create-vite@6.1.1
Ok to proceed? (y)
√ Project name: ... vite-project
√ Select a framework: » Vanilla
√ Select a variant: » TypeScript
...
Done. Now run:
cd vite-project
npm install
npm run dev
Simple Rendering
On the main page, created custom classes to render musical notes as a simple example.
Note.ts
export class Note {
constructor(public pitch: string, public x: number, public y: number) {}
render(ctx: CanvasRenderingContext2D) {
// Draw the note head as a filled circle
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, Math.PI * 2);
ctx.fill();
// Draw the stem
ctx.beginPath();
ctx.moveTo(this.x + 5, this.y);
ctx.lineTo(this.x + 5, this.y - 30);
ctx.stroke();
// Add pitch text
ctx.font = "12px Arial";
ctx.fillText(this.pitch, this.x - 10, this.y + 20);
}
}
Renderer.ts
import { Staff } from "./Staff";
import { Note } from "./Note";
export class Renderer {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
constructor(canvasId: string) {
const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
if (!canvas) throw new Error(`Canvas with ID "${canvasId}" not found.`);
this.canvas = canvas;
this.ctx = canvas.getContext("2d")!;
}
render(staff: Staff, notes: Note[]) {
// Clear the canvas
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Render the staff
staff.render(this.ctx);
// Render the notes
notes.forEach(note => note.render(this.ctx));
}
}