@stringsync/vexml
Version:
MusicXML to Vexflow
54 lines (53 loc) • 2.32 kB
JavaScript
import * as vexflow from 'vexflow';
import * as components from '../components';
import * as elements from '../elements';
import { Score } from './score';
import { DEFAULT_CONFIG } from '../config';
import { NoopLogger, Stopwatch } from '../debug';
import { Document } from './document';
export class Renderer {
config;
log;
constructor(opts) {
this.config = { ...DEFAULT_CONFIG, ...opts?.config };
this.log = opts?.logger ?? new NoopLogger();
}
render(div, document) {
const width = this.config.WIDTH ?? undefined;
const height = this.config.HEIGHT ?? undefined;
let root;
let container;
let renderer;
switch (this.config.DRAWING_BACKEND) {
case 'svg':
root = components.Root.svg(div, width, height);
container = root.getVexflowContainerElement();
renderer = new vexflow.Renderer(container, vexflow.Renderer.Backends.SVG);
break;
case 'canvas':
root = components.Root.canvas(div, width, height);
container = root.getVexflowContainerElement();
renderer = new vexflow.Renderer(container, vexflow.Renderer.Backends.CANVAS);
break;
default:
this.log.info(`backend not specified or supported, defaulting to 'svg'`);
root = components.Root.svg(div, width, height);
container = root.getVexflowContainerElement();
renderer = new vexflow.Renderer(container, vexflow.Renderer.Backends.SVG);
}
const stopwatch = Stopwatch.start();
const renderingDocument = new Document(document);
const scoreRender = new Score(this.config, this.log, renderingDocument, this.config.WIDTH).render();
const ctx = renderer.resize(scoreRender.rect.w, scoreRender.rect.h).getContext();
const scoreElement = elements.Score.create(this.config, this.log, renderingDocument, ctx, root, scoreRender);
scoreElement.render();
const lap = stopwatch.lap();
if (lap < 1) {
this.log.info(`rendered score in ${lap.toFixed(3)}ms`);
}
else {
this.log.info(`rendered score in ${Math.round(lap)}ms`);
}
return scoreElement;
}
}