vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature.
118 lines (100 loc) • 3.06 kB
text/typescript
// [VexFlow](https://vexflow.com) - Copyright (c) Mohit Muthanna 2010.
// Author Taehoon Moon 2014
import { Font, FontInfo, FontStyle, FontWeight } from './font';
import { Stave } from './stave';
import { StaveModifier, StaveModifierPosition } from './stavemodifier';
import { TextJustification, TextNote } from './textnote';
import { Category } from './typeguard';
import { RuntimeError } from './util';
export class StaveText extends StaveModifier {
static get CATEGORY(): string {
return Category.StaveText;
}
static TEXT_FONT: Required<FontInfo> = {
family: Font.SERIF,
size: 16,
weight: FontWeight.NORMAL,
style: FontStyle.NORMAL,
};
protected options: {
shift_x: number;
shift_y: number;
justification: number;
};
protected text: string;
protected shift_x?: number;
protected shift_y?: number;
constructor(
text: string,
position: number,
options: { shift_x?: number; shift_y?: number; justification?: number } = {}
) {
super();
this.setWidth(16);
this.text = text;
this.position = position;
this.options = {
shift_x: 0,
shift_y: 0,
justification: TextNote.Justification.CENTER,
...options,
};
this.resetFont();
}
setStaveText(text: string): this {
this.text = text;
return this;
}
setShiftX(x: number): this {
this.shift_x = x;
return this;
}
setShiftY(y: number): this {
this.shift_y = y;
return this;
}
setText(text: string): this {
this.text = text;
return this;
}
draw(stave: Stave): this {
const ctx = stave.checkContext();
this.setRendered();
ctx.save();
ctx.setLineWidth(2);
ctx.setFont(this.textFont);
const text_width = ctx.measureText('' + this.text).width;
let x;
let y;
switch (this.position) {
case StaveModifierPosition.LEFT:
case StaveModifierPosition.RIGHT:
y = (stave.getYForLine(0) + stave.getBottomLineY()) / 2 + this.options.shift_y;
if (this.position === StaveModifierPosition.LEFT) {
x = stave.getX() - text_width - 24 + this.options.shift_x;
} else {
x = stave.getX() + stave.getWidth() + 24 + this.options.shift_x;
}
break;
case StaveModifierPosition.ABOVE:
case StaveModifierPosition.BELOW:
x = stave.getX() + this.options.shift_x;
if (this.options.justification === TextJustification.CENTER) {
x += stave.getWidth() / 2 - text_width / 2;
} else if (this.options.justification === TextJustification.RIGHT) {
x += stave.getWidth() - text_width;
}
if (this.position === StaveModifierPosition.ABOVE) {
y = stave.getYForTopText(2) + this.options.shift_y;
} else {
y = stave.getYForBottomText(2) + this.options.shift_y;
}
break;
default:
throw new RuntimeError('InvalidPosition', 'Value Must be in Modifier.Position.');
}
ctx.fillText('' + this.text, x, y + 4);
ctx.restore();
return this;
}
}