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

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));
  }
}

D3 Stacked Plot Example