Native Shell
Native Shell:AI 生成的 UI,在你的应用中原生呈现,覆盖每个平台。iOS、Android、macOS、Windows 与 Linux 上的应用、GPUI 应用与网页在运行时加载已签名、沙箱隔离的 TSX 模块并绘制 th
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证SVG chord and scale diagram renderer for fretted, keyboard and bowed instruments. Zero dependencies, 23 kb.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗SVG chord and scale diagram renderer for fretted, keyboard, and bowed instruments. Zero runtime dependencies. 23 kb compiled bundle.
notae renders publication-quality SVG diagrams directly from a chord or scale description. No canvas, no DOM manipulation, no dependencies — just a function that returns an SVG string.
// Guitar — barre chord with finger numbers
Notae.renderFretboard({
name: 'F major',
frets: [1, 3, 3, 2, 1, 1],
fingers: [1, 3, 4, 2, 1, 1],
barres: [{ fret: 1, startString: 1, endString: 6 }],
tuning: ['E', 'A', 'D', 'G', 'B', 'E'],
})
// Banjo — drone string offset, scale with multiple notes per string
Notae.renderFretboard({
name: 'G major',
frets: [[5, 7], [0, 2, 4, 5], [0, 2, 4, 5], [0, 1, 3, 5], [0, 2, 4]],
tuning: ['G', 'D', 'G', 'B', 'D'],
stringOffset: [5, 0, 0, 0, 0],
root: 'G',
}, { numFrets: 7 })
// Piano — chord with per-key colors
Notae.renderPiano({
name: 'G major',
keys: ['G3', 'B3', 'D4'],
colors: ['#cc2244', '#5aaa5a', '#4466cc'],
root: 'G',
})
// Violin — G major scale, 1st position
Notae.renderBowed({
name: 'G major',
strings: [[0, 2, 4, 5], [0, 2, 4, 5], [0, 2, 3, 5], [0, 2, 3, 5]],
numSlots: 5,
tuning: ['G', 'D', 'A', 'E'],
position: 1,
root: 'G',
})
Browser — CDN (jsDelivr)
<script src="https://cdn.jsdelivr.net/gh/memoriainfinita/notae@master/dist/notae.js"></script>
Build from source
pnpm install
pnpm run build:lib # src/index.ts → dist/notae.js (IIFE, global Notae)
pnpm run dev # watch mode for the demo
Any fretted instrument: guitar, bass, ukulele, banjo, mandolin.
renderFretboard(chord: FretboardChord, style?: StyleOptions): string
// Barre chord with finger numbers
renderFretboard({
name: 'F major',
frets: [1, 3, 3, 2, 1, 1],
fingers: [1, 3, 4, 2, 1, 1],
barres: [{ fret: 1, startString: 1, endString: 6 }],
tuning: ['E', 'A', 'D', 'G', 'B', 'E'],
root: 'F',
})
// Scale position with per-dot colors (root · third · fifth)
renderFretboard({
name: 'G major',
frets: [3, 2, 0, 0, 0, 3],
tuning: ['E', 'A', 'D', 'G', 'B', 'E'],
root: 'G',
colors: ['#cc2244', '#4466cc', null, null, '#4466cc', '#cc2244'],
})
// Scale — multiple notes per string
renderFretboard({
name: 'Am pentatonic',
frets: [[5, 8], [5, 7], [5, 7], [5, 7], [5, 8], [5, 8]],
tuning: ['E', 'A', 'D', 'G', 'B', 'E'],
baseFret: 5,
root: 'A',
}, { numFrets: 4, orientation: 'horizontal' })
// Banjo — drone string with offset
renderFretboard({
name: 'G',
frets: [5, 0, 0, 0, 0],
tuning: ['G', 'D', 'G', 'B', 'D'],
stringOffset: [5, 0, 0, 0, 0],
root: 'G',
})
FretboardChord
| Field | Type | Description |
|---|---|---|
name | string | Chord or scale name (shown above diagram) |
frets | (number | number[])[] | Fret per string; -1 = muted, 0 = open. Array for multiple notes (scales). |
fingers? | number[] | Finger number per string (0 = none) |
barres? | { fret, startString, endString }[] | Barre indicators. Strings are 1-indexed from low. |
tuning? | string[] | Open-string names, used as labels |
baseFret? | number | First fret shown — triggers fret label |
stringOffset? | number[] | Fret where each string starts (banjo drone) |
root? | string | Root note — enables showDegrees |
colors? | (string | null)[] | Per-string dot color override |
dotColors? | (string | null)[][] | Per-dot color, parallel to each string's frets; wins over colors |
dotLabels? | (string | null)[][] | Per-dot text, parallel to each string's frets; wins over degrees, names and fingers ('' = none) |
renderPiano(chord: PianoChord, style?: StyleOptions): string
// Chord with finger numbers
renderPiano({
name: 'Cmaj7',
keys: ['C4', 'E4', 'G4', 'B4'],
fingers: [1, 2, 3, 5],
root: 'C',
})
// Scale over 2 octaves
renderPiano({
name: 'Am blues',
keys: ['A3', 'C4', 'D4', 'Eb4', 'E4', 'G4', 'A4', 'C5', 'D5', 'Eb5', 'E5', 'G5'],
root: 'A',
range: { from: 'A3', to: 'G5' },
})
// Per-key colors with scale degrees
renderPiano({
name: 'F# harmonic minor',
keys: ['F#3', 'G#3', 'A3', 'B3', 'C#4', 'D4', 'F4', 'F#4'],
colors: ['#cc2244', null, '#4466cc', null, '#5aaa5a', null, null, '#cc2244'],
root: 'F#',
}, { showDegrees: true })
PianoChord
| Field | Type | Description |
|---|---|---|
name | string | Chord or scale name |
keys | string[] | Active keys, e.g. 'C4', 'Bb3', 'F#5' |
fingers? | number[] | Finger number per key |
root? | string | Root note — enables showDegrees |
range? | { from: string, to: string } | Visible range of the keyboard |
colors? | (string | null)[] | Per-key color override |
Every key <rect> carries data-note (e.g. data-note="C#4", sharp spelling), so a host can attach click handlers without depending on render order.
Violin, viola, cello — slot-based (semitones from open string).
renderBowed(chord: BowedChord, style?: StyleOptions): string
// G major scale, violin, 1st position
renderBowed({
name: 'G major',
strings: [[0, 2, 4, 5], [0, 2, 4, 5], [0, 2, 3, 5], [0, 2, 3, 5]],
numSlots: 5,
tuning: ['G', 'D', 'A', 'E'],
position: 1,
root: 'G',
})
// Position chord, horizontal layout
renderBowed({
name: 'D',
strings: [3, 2, 1, null],
fingers: [3, 2, 1, null],
tuning: ['G', 'D', 'A', 'E'],
position: 3,
}, { orientation: 'horizontal' })
BowedChord
| Field | Type | Description |
|---|---|---|
name | string | Chord or scale name |
strings | (number | number[] | null)[] | Slot per string (semitones from open). null = not played. |
fingers? | (number | null)[] | Finger number per string |
tuning? | string[] | Open-string names |
position? | number | Position indicator shown left of diagram |
numSlots? | number | Number of slots to display (default: 4) |
root? | string | Root note — enables showDegrees |
All renderers accept an optional second argument. Every field is optional.
renderFretboard(chord, {
// Colors
dotColor: '#5aaa5a',
dotTextColor: '#ffffff',
chordNameColor: '#000000',
nutColor: '#333333',
stringColor: '#aaaaaa',
fretColor: '#cccccc',
barreColor: '#5aaa5a',
// Sizes
dotRadius: 9,
stringSpacing: 19,
fretSpacing: 23,
numFrets: 5,
nutWidth: 4,
// Layout
orientation: 'vertical', // 'vertical' | 'horizontal'
leftHanded: false,
showFingerNumbers: true,
showOpenNotes: false, // fretboard: a 0 among a string's frets drawn as the open ring
showDegrees: false, // requires chord.root
showNoteNames: false, // fretboard: note name on each dot (showDegrees wins)
preferFlats: false, // spell note names with flats (Bb, not A#)
showStringLabels: true,
stringLabelMode: 'tuning', // 'tuning' | 'notes'
// String / note labels
stringLabelGap: 4, // gap between nut/fret and label text (px)
pianoNoteLabelGap: 4, // gap between piano keys and note label text (px)
bowedTickSize: 5, // length of slot tick marks on bowed diagrams (px)
fretLabelGapH: 8, // bottom padding reserve for fret label in horizontal orientation (px)
// Filter effects
filterStyle: 'clean', // 'clean' | 'shadow' | 'glow'
shadowColor: '#000000',
shadowX: 2, shadowY: 3, shadowBlur: 2, shadowOpacity: 0.25,
glowColor: '#5aaa5a', glowBlur: 2.5, glowOpacity: 0.8,
// Box
backgroundColor: 'transparent',
borderColor: 'transparent',
borderWidth: 0,
borderRadius: 0,
diagramPadding: 0,
})
Full list of defaults in src/types.ts.
notae pairs with UMT for music theory computation. UMT generates the note data; notae renders the diagram.
<script src="https://cdn.jsdelivr.net/gh/memoriainfinita/notae@master/dist/notae.js"></script>
<script src="https://cdn.jsdelivr.net/gh/memoriainfinita/[email protected]/dist/umt.js"></script>
<script>
// Chord → piano
const chord = UMT.parseChordSymbol('Cmaj9');
const keys = chord.getNotes().map(n => n.name);
document.getElementById('piano').innerHTML = Notae.renderPiano({ name: 'Cmaj9', keys });
// Chord → fretboard voicings
const voicings = UMT.getFretboardVoicings(chord, UMT.GUITAR_STANDARD);
document.getElementById('fret').innerHTML = Notae.renderFretboard({ name: 'Cmaj9', ...voicings[0] });
// Scale → fretboard positions
const scale = UMT.parseScaleSymbol('D dorian');
const boxes = UMT.getFretboardScalePositions(scale, UMT.GUITAR_STANDARD);
boxes.slice(0, 5).forEach((box, i) => {
document.getElementById('box-' + i).innerHTML = Notae.renderFretboard(
{ name: 'D dorian', ...box },
{ numFrets: 4 }
);
});
</script>
pnpm test # 70 unit tests via vitest (fretboard, piano, bowed)
GPL-3.0. See LICENSE.
Developed by @memoriainfinita with the assistance of Claude (Anthropic): Opus 4.8, Sonnet 4.6 and Haiku 4.5.