版本:1.0
更新日期:2026-01-30
五线谱渲染器(StaffRenderer)是一个基于 SVG 的五线谱渲染引擎,提供:
import { StaffRenderer, createStaffRenderer } from '@/renderers/staff';
import { MusicXMLParser } from '@/music-core/parser';
// 1. 解析 MusicXML
const parser = new MusicXMLParser();
const result = parser.parse(xmlString);
const score = result.score;
// 2. 创建渲染器
const renderer = createStaffRenderer({
container: document.getElementById('score-container'),
systemWidth: 800,
staffLineSpacing: 10,
});
// 3. 加载并渲染
renderer.load(score);
renderer.render();
// 4. 获取统计信息
const stats = renderer.getStats();
console.log(`渲染完成: ${stats.noteCount} 个音符, 耗时 ${stats.totalTime}ms`);
五线谱渲染器主类。
class StaffRenderer {
constructor(options?: StaffRendererOptions);
// 设置容器
setContainer(container: HTMLElement | string): void;
// 加载乐谱数据
load(score: Score): void;
// 渲染
render(): void;
// 获取统计信息
getStats(): StaffRenderStats;
// 获取 SVG 元素
getSVGElement(): SVGSVGElement | null;
// 获取/更新配置
getConfig(): StaffRenderConfig;
updateConfig(config: Partial<StaffRenderConfig>): void;
}
interface StaffRendererOptions extends Partial<StaffRenderConfig> {
container?: HTMLElement | string;
}
interface StaffRenderStats {
layoutTime: number; // 布局耗时(ms)
drawTime: number; // 绘制耗时(ms)
totalTime: number; // 总耗时(ms)
measureCount: number; // 小节数
noteCount: number; // 音符数
systemCount: number; // 行数
}
| 绘制器 | 说明 | 主要方法 |
|---|---|---|
StaveDrawer |
谱表绘制 | drawStave(), drawLedgerLines() |
ClefDrawer |
谱号绘制 | drawClef() |
KeySignatureDrawer |
调号绘制 | drawKeySignature() |
TimeSignatureDrawer |
拍号绘制 | drawTimeSignature() |
NoteHeadDrawer |
符头绘制 | drawNoteHead() |
StemDrawer |
符干绘制 | drawStem(), drawChordStem() |
FlagDrawer |
符尾绘制 | drawFlags() |
BeamDrawer |
符杠绘制 | drawBeam(), drawBeamGroup() |
RestDrawer |
休止符绘制 | drawRest() |
DotDrawer |
附点绘制 | drawDots(), drawRestDots() |
BarlineDrawer |
小节线绘制 | drawBarline() |
AccidentalDrawer |
临时升降号绘制 | drawAccidental() |
| 绘制器 | 说明 | 主要方法 |
|---|---|---|
TieDrawer |
延音线绘制 | drawTie() |
SlurDrawer |
圆滑线绘制 | drawSlur() |
| 绘制器 | 说明 | 主要方法 |
|---|---|---|
DynamicsDrawer |
力度记号 | drawDynamic(), drawWedge() |
ArticulationsDrawer |
演奏技法 | drawArticulation(), drawArticulations() |
OrnamentsDrawer |
装饰记号 | drawOrnament(), drawTrillLine() |
FermataDrawer |
延音记号 | drawFermata() |
DirectionDrawer |
方向标记 | drawWords(), drawMetronome(), drawWedge() |
LyricDrawer |
歌词绘制 | drawLyrics() |
import { ArticulationsDrawer, OrnamentsDrawer } from '@/renderers/staff';
// 演奏技法
const articulationsDrawer = new ArticulationsDrawer({ staffLineSpacing: 10 });
const staccato = articulationsDrawer.drawArticulation('staccato', x, y, 'above');
// 装饰记号
const ornamentsDrawer = new OrnamentsDrawer();
const trill = ornamentsDrawer.drawOrnament('trill-mark', x, y);
负责计算系统(行)布局和小节分配。
class StaffLayoutEngine {
constructor(config?: Partial<StaffRenderConfig>);
// 计算布局
calculateLayout(measures: MeasureInfo[]): StaffLayoutResult;
// 估算小节宽度
estimateMeasureWidth(noteCount: number, totalDuration: number): number;
// 更新配置
updateConfig(config: Partial<StaffRenderConfig>): void;
}
负责计算音符在五线谱上的位置。
class NoteLayoutCalculator {
constructor(config?: Partial<StaffRenderConfig>);
// 计算音符位置
calculateNotePosition(
pitch: PitchInfo,
clef: ClefType,
staffTopY: number
): Omit<NotePosition, 'x'>;
// 获取谱表位置
getStaffPosition(pitch: PitchInfo, clef: ClefType): number;
// 位置转 Y 坐标
staffPositionToY(staffPosition: number, staffTopY: number): number;
// 计算加线
calculateLedgerLines(staffPosition: number): { needsLedgerLines: boolean; ledgerLineCount: number };
// 计算符干方向
calculateStemDirection(staffPosition: number): 1 | -1;
}
通用渲染缓存,使用 LRU 策略。
class RenderCache<T = any> {
constructor(config?: Partial<CacheConfig>);
get(key: string): T | undefined;
set(key: string, value: T): void;
has(key: string): boolean;
delete(key: string): boolean;
clear(): void;
// 带缓存的计算
getOrCompute(key: string, compute: () => T): T;
// 获取统计
getStats(): { size: number; totalHits: number; enabled: boolean };
}
布局专用缓存,提供便捷的键生成方法。
class LayoutCache extends RenderCache {
static notePositionKey(step: string, octave: number, clef: string, staffTopY: number): string;
static measureLayoutKey(measureIndex: number, width: number): string;
static systemLayoutKey(systemIndex: number, measureCount: number): string;
}
批量渲染器,使用 DocumentFragment 和 requestAnimationFrame 优化 DOM 操作。
class BatchRenderer {
constructor(options?: Partial<BatchRenderOptions>);
setContainer(container: SVGElement): void;
addTask(task: RenderTask): void;
addTasks(tasks: RenderTask[]): void;
// 同步渲染
renderSync(): SVGElement[];
// 异步渲染(分批)
renderAsync(): Promise<SVGElement[]>;
cancel(): void;
}
懒加载渲染器,只渲染可视区域内的内容。
class LazyRenderer {
constructor(buffer?: number);
setContainer(container: HTMLElement): void;
registerItem(id: string, y: number, height: number, render: () => SVGElement): void;
clear(): void;
renderAll(): SVGElement[];
}
interface StaffRenderConfig {
// 谱表尺寸
staffLineSpacing: number; // 谱线间距(默认: 10)
staffHeight: number; // 谱表高度(默认: 40)
staffLeftMargin: number; // 左边距(默认: 20)
staffRightMargin: number; // 右边距(默认: 20)
staffSpacing: number; // 谱表间距(默认: 80)
// 系统/行配置
systemWidth: number; // 系统宽度(默认: 800)
systemTopMargin: number; // 上边距(默认: 60)
systemSpacing: number; // 系统间距(默认: 120)
// 音符配置
quarterNoteSpacing: number; // 四分音符间距(默认: 40)
minNoteSpacing: number; // 最小间距(默认: 20)
noteHeadWidth: number; // 符头宽度(默认: 12)
noteHeadHeight: number; // 符头高度(默认: 10)
// 符干配置
stemLength: number; // 符干长度(默认: 3.5)
stemWidth: number; // 符干宽度(默认: 1.2)
// 符杠配置
beamThickness: number; // 符杠厚度(默认: 5)
beamSpacing: number; // 符杠间距(默认: 4)
// 谱号配置
clefScale: number; // 谱号大小(默认: 3.5)
clefLeftMargin: number; // 谱号左边距(默认: 8)
// 调号配置
accidentalSpacing: number; // 升降号间距(默认: 8)
accidentalScale: number; // 升降号大小(默认: 2.5)
// 拍号配置
timeSignatureFontSize: number; // 拍号字体大小(默认: 28)
timeSignatureMargin: number; // 拍号边距(默认: 10)
// 小节线配置
barlineWidth: number; // 小节线宽度(默认: 1)
doubleBarlineSpacing: number; // 双线间距(默认: 4)
// 字体配置
fontFamily: string; // 主字体
musicFontFamily: string; // 音乐符号字体
// 颜色配置
staffLineColor: string; // 谱线颜色(默认: #000000)
noteColor: string; // 音符颜色(默认: #000000)
textColor: string; // 文字颜色(默认: #000000)
// 显示配置
showLyrics: boolean; // 显示歌词(默认: true)
showMeasureNumbers: boolean; // 显示小节号(默认: true)
debug: boolean; // 调试模式(默认: false)
}
| 版本 | 日期 | 更新内容 |
|---|---|---|
| 1.0 | 2026-01-30 | 初始版本,包含所有核心功能 |