Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
28e0820
Add playback note highlighting with position cursor and auto-scroll
zz85 Mar 3, 2026
2124eb0
Add page layout mode with Letter/A4 paper sizes
zz85 Mar 3, 2026
6875572
Add highlighter overlay style, font size logging, and auto-scroll toggle
zz85 Mar 3, 2026
fd16bff
Add solo/mute per staff, piano keyboard visualization, and features T…
zz85 Mar 3, 2026
b4bfa5f
Fix piano keyboard proportions, default font size 28, keep highlights…
zz85 Mar 3, 2026
404eea0
Fix chord accidental resolution and duplicate note in MIDI playback
zz85 Mar 3, 2026
78ce21e
Update features TODO: mark completed milestones and add new planned i…
zz85 Mar 3, 2026
a3274f4
Add dynamic music font switching with companion text fonts and SMuFL …
zz85 Mar 4, 2026
e406826
Categorize font selector dropdown with optgroups and descriptions
zz85 Mar 4, 2026
97aa0d0
Fix dynamic marking Y position: remove erroneous negation
zz85 Mar 4, 2026
2e8a1bc
Add MIDI import: load .mid/.midi files as rendered score
zz85 Mar 5, 2026
b676c9e
Add GitHub Actions workflow to run tests on push
zz85 Mar 5, 2026
e744fe0
Add Tier 2 visual rendering: articulations, hairpins, voltas, triplet…
zz85 Mar 5, 2026
ecd1963
Spring-rod spacing model with 6 layout improvements
zz85 Mar 5, 2026
671c6bd
Fix chord accidental alignment: use pure offsetX, no cursor advance
zz85 Mar 5, 2026
23c5af9
Refine spring-rod spacing: fix barline flush, factor accuracy, post-b…
zz85 Mar 5, 2026
ae99f95
Fix ties, beams, triplet brackets, grace notes, and chord anchoring
zz85 Mar 6, 2026
3319a33
Fix beam engraving: correct coordinate system, stem lengths, and slan…
zz85 Mar 6, 2026
472d179
Simplify beam placement: remove isNonMonotonic, use optimal offset so…
zz85 Mar 6, 2026
23e50ae
Professional tie/slur engraving: cubic bezier curves, separate Slur c…
zz85 Mar 10, 2026
5734bf9
Add spacing density and rod-spring balance sliders for interactive sp…
zz85 Mar 11, 2026
94b9083
Add duration proportionality slider and persist last loaded song to l…
zz85 Mar 12, 2026
91f0a17
Add visual test suite and fix scoreElm ghost global in Drawing.draw()
zz85 Mar 12, 2026
4b82586
Add 38 synthetic visual tests: isolated feature fixtures independent …
zz85 Mar 12, 2026
d728a92
Fix KeySignature width=undefined for C major causing NaN cursor position
zz85 Mar 12, 2026
24dc177
Playback: per-staff GM instruments, tempo beat-unit conversion, noteO…
zz85 Mar 12, 2026
a0c2fb8
Add per-staff MIDI transposition for transposing instruments
zz85 Mar 12, 2026
34ff60b
Fix hairpin rendering: correct wedge geometry and span-to-dynamic cal…
zz85 Mar 12, 2026
e8e8519
Fix ledger line rendering: scale with notehead, fix above-staff range…
zz85 Mar 13, 2026
b757f39
Dynamic velocity + repeat/volta playback
zz85 Mar 13, 2026
2a867d9
Replace hardcoded pixel values with font-size-relative dimensions
zz85 Mar 13, 2026
02cedee
Scale initial spacing by rod/spring balance to affect line breaking
zz85 Mar 13, 2026
f166366
Two-pass line breaking: reflow sparse systems for better fill
zz85 Mar 13, 2026
f103e52
Playback cursor spans all staves in the system
zz85 Mar 13, 2026
daecda2
Update .gitignore: exclude binaries, .DS_Store, build artifacts
zz85 Mar 13, 2026
fa18125
Playback highlight modes: bar overlay, columnar, and mode selector
zz85 Mar 13, 2026
9ea7ffd
Click-to-seek: clicking on the score positions the playback cursor
zz85 Mar 13, 2026
2a70d6f
Menu UI refresh: flexbox toolbar, segmented layout/orientation contro…
zz85 Mar 13, 2026
76920d5
Toolbar: two-row layout, logo links to GitHub, clean indentation
zz85 Mar 13, 2026
0e602d3
Fix articulation alignment: close-to-notehead Y, correct X centering,…
zz85 Mar 13, 2026
176edf0
Fix articulation distance: ±2 with line-nudge, chord deduplication, u…
zz85 Mar 13, 2026
abc3741
Stave-to-clef gap: 1.1 staff spaces for initial and courtesy clefs
zz85 Mar 13, 2026
b0d700c
Grace note engraving: scaled stems/flags/beams, acciaccatura slash, s…
zz85 Mar 13, 2026
07f874d
Beams: standard engraving thickness (0.5sp) and separation (0.25sp gap)
zz85 Mar 13, 2026
0f46124
Triplets: tighter numeral placement, clean constructor, stem-down and…
zz85 Mar 13, 2026
e9d9169
Display bar numbers at the start of each system
zz85 Mar 13, 2026
2396966
Render grand staff braces using SMuFL glyph instead of bezier outline
zz85 Mar 13, 2026
83e4f0f
Dynamic inter-staff spacing based on content extents
zz85 Mar 13, 2026
70dd889
System barline connecting all staves; brace/bracket visual test fixtures
zz85 Mar 13, 2026
a74c2c1
Update plan docs to reflect current implementation status
zz85 Mar 13, 2026
d53da75
Print emulation: WebGL2 ink bleed post-processing filter
zz85 Mar 13, 2026
db983ad
Fix ink bleed for all layout modes; paper color picker; score-pinned …
zz85 Mar 13, 2026
255941d
Ink bleed: page-mode background masking, advanced controls panel
zz85 Mar 13, 2026
476ac74
README: add v2.3 changelog and visual test suite link
zz85 Mar 14, 2026
121f72e
Fix chord tie direction inversion; add engraving rules reference
zz85 Mar 14, 2026
a8fa9f2
Calibrate engraving constants against MuseScore/LilyPond/OSMD
zz85 Mar 14, 2026
a55f84c
Differentiate barline gap for notes vs key/time sigs; fix accidental gap
zz85 Mar 14, 2026
f8443e5
Fix brace position, barline-note spacing, engraving rules docs
zz85 Mar 14, 2026
ad15468
Align brace tips with stave edge using glyph bbox
zz85 Mar 14, 2026
1b3711e
Chord second displacement: alternating noteheads for clusters
zz85 Mar 14, 2026
3849ce9
Document cross-staff vertical alignment rule; add visual test fixtures
zz85 Mar 15, 2026
1bd63ec
Fix grand staff barlines: continuous from top to bottom
zz85 Mar 15, 2026
8b8032c
Parser: V175 staff connection flags from staffType; parse color field
zz85 Mar 15, 2026
ce78eff
Fix Segno/Coda advancing cursor: flow directions are non-spacing
zz85 Mar 15, 2026
3d43a68
Grace notes: zero display timing for cross-staff alignment
zz85 Mar 15, 2026
6c72287
README: add v2.3 screenshot and expand changelog with missing features
zz85 Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Tests

on:
push:
branches: ['**']
pull_request:
branches: ['**']

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- run: bun install

- run: bun test test/*.test.js
24 changes: 21 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
.aider*

# Integration test ephemeral output (screenshots and AI reports)
# OS metadata
.DS_Store
Thumbs.db

# Dependencies
node_modules/
bun.lock

# Build/test artifacts
test-results/
test/integration/output/
test/integration/reports/

# Playwright cache
node_modules/
# Binary files and reference materials
*.exe
*.iso
*.bin
*.paf.exe
nwc-extract/
nwc2xml
references/*.iso
references/*.bin
references/*.exe
vendor/.DS_Store
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,38 @@ And if you like this project, you can also chat me up [@blurspline on twitter](h

### [Try it](http://zz85.github.io/nwc-viewer/)

![screen shot](screenshots/notably-v2.2.png)
![screen shot](screenshots/notably-v2.3.png)

## Changelog

### v2.3 - March 2026
- **Print emulation** — WebGL2 ink-bleed post-processing filter for paper-like rendering; paper color picker; page-mode background masking
- **Page layout mode** — Letter and A4 paper sizes with proper page breaks
- **Advanced controls panel** — collapsible panel with spacing density, rod/spring balance, duration proportionality, and ink-bleed sliders
- **Dynamic inter-staff spacing** — content-aware vertical gaps based on actual note extents rather than fixed multipliers
- **System barline** — single barline connecting all staves at the left edge of each system
- **Grand staff braces** — SMuFL glyph-rendered `{` brace for piano/organ staves, tips aligned to stave edge via glyph bbox
- **Bar numbers** — measure numbers displayed at the start of each system
- **Articulations** — staccato, accent, tenuto, marcato, staccatissimo, fermata; correct stem-side placement with staff-line avoidance
- **Grace notes** — acciaccatura (slashed) and appoggiatura; scaled stems/flags/beams, stems forced up; zero display timing for cross-staff alignment
- **Triplet brackets** — bracket-less numeral for beamed groups; bracketed for unbeamed/rest-containing groups; stem-side placement
- **Chord second displacement** — alternating noteheads for cluster chords
- **Beam engraving** — standard 0.5 staff-space thickness and 0.25 staff-space separation per Gould/Dorico spec
- **Playback highlights** — bar overlay, columnar, and note-column modes; click-to-seek; auto-scroll
- **Piano keyboard** — on-screen keyboard visualization with solo/mute per staff
- **Per-staff MIDI** — GM instrument assignment and transposition per staff; dynamic velocity; repeat/volta playback
- **Hairpin rendering** — correct wedge geometry spanning note ranges
- **Volta brackets** — first/second ending brackets rendered above staff
- **Multiple music fonts** — dynamic font switching with 20+ bundled fonts (Finale Maestro, Jazz, Broadway, Leland, Petaluma, Leipzig, Sebastian, etc.) and matched companion text fonts
- **MIDI import** — load `.mid`/`.midi` files as rendered score
- **Spacing model** — spring-rod spacing with duration proportionality; two-pass line breaking; interactive sliders
- **Engraving rules** — constants calibrated against MuseScore, LilyPond, and OSMD; font-size-relative dimensions replacing hardcoded pixels
- **Professional ties/slurs** — cubic bezier curves, separate Slur class, staff-line collision avoidance, beam slope clamping
- **Parser** — V175 staff connection flags from staffType; color field parsing; Segno/Coda non-spacing fix
- **UI refresh** — two-row toolbar, segmented layout/orientation controls, logo links to GitHub, localStorage persistence for last loaded song
- **CI** — GitHub Actions workflow running tests on push
- 530 unit tests; 50+ synthetic visual test fixtures (open `test/visual/index.html`)

### v2.2 - March 2026
- **Wrap layout** with DP-optimal line breaking and anchor-point justification
- **Lyrics** — syllable assignment respecting slur/tie/LyricSyllable rules, inter-syllable dashes
Expand Down Expand Up @@ -94,6 +122,7 @@ See [lib/nwc2xml/README.md](lib/nwc2xml/README.md) for more details.

- **[index.html](index.html)** - Music viewer and player for NWC files
- **[nwc2xml_converter.html](nwc2xml_converter.html)** - NWC to MusicXML converter with drag-and-drop interface
- **[test/visual/index.html](test/visual/index.html)** - Visual test suite: isolated rendering fixtures for individual notation features

## Internals

Expand Down
Loading
Loading