VexFlow - Copyright (c) Mohit Muthanna 2010. Author Radosaw Eichler 2012
import { Flow } from './tables';
import { Modifier } from './modifier';
import { StaveModifier } from './stavemodifier';
import { Glyph } from './glyph';
export class StaveTempo extends StaveModifier {
static get CATEGORY() { return 'stavetempo'; }
constructor(tempo, x, shift_y) {
super();
this.setAttribute('type', 'StaveTempo');
this.tempo = tempo;
this.position = Modifier.Position.ABOVE;
this.x = x;
this.shift_x = 10;
this.shift_y = shift_y;
this.font = {
family: 'times',
size: 14,
weight: 'bold',
};
this.render_options = {
glyph_font_scale: 30, // font size for note
};
}
getCategory() { return StaveTempo.CATEGORY; }
setTempo(tempo) { this.tempo = tempo; return this; }
setShiftX(x) { this.shift_x = x; return this; }
setShiftY(y) { this.shift_y = y; return this; }
draw(stave, shift_x) {
const ctx = stave.checkContext();
const options = this.render_options;
FIXME: What does the ‘38’ mean? Why 38? Is that supposed to be the default font size for standard notation?
const scale = options.glyph_font_scale / 38;
const name = this.tempo.name;
const duration = this.tempo.duration;
const dots = this.tempo.dots;
const bpm = this.tempo.bpm;
const font = this.font;
let x = this.x + this.shift_x + shift_x;
const y = stave.getYForTopText(1) + this.shift_y;
ctx.save();
if (name) {
ctx.setFont(font.family, font.size, font.weight);
ctx.fillText(name, x, y);
x += ctx.measureText(name).width;
}
if (duration && bpm) {
ctx.setFont(font.family, font.size, 'normal');
if (name) {
x += ctx.measureText(' ').width;
ctx.fillText('(', x, y);
x += ctx.measureText('(').width;
}
const code = Flow.durationToGlyph(duration);
x += 3 * scale;
Glyph.renderGlyph(ctx, x, y, options.glyph_font_scale, code.code_head);
x += code.getWidth() * scale;
Draw stem and flags
if (code.stem) {
let stem_height = 30;
if (code.beam_count) stem_height += 3 * (code.beam_count - 1);
stem_height *= scale;
const y_top = y - stem_height;
ctx.fillRect(x - scale, y_top, scale, stem_height);
if (code.flag) {
Glyph.renderGlyph(ctx, x, y_top, options.glyph_font_scale, code.code_flag_upstem);
if (!dots) x += 6 * scale;
}
}
Draw dot
for (let i = 0; i < dots; i++) {
x += 6 * scale;
ctx.beginPath();
ctx.arc(x, y + 2 * scale, 2 * scale, 0, Math.PI * 2, false);
ctx.fill();
}
ctx.fillText(' = ' + bpm + (name ? ')' : ''), x + 3 * scale, y);
}
ctx.restore();
return this;
}
}