VexFlow - Copyright (c) Mohit Muthanna 2010.
Author Larry Kuhns 2011
import { Flow } from './tables';
import { StaveModifier } from './stavemodifier';
export class Barline extends StaveModifier {
static get CATEGORY() { return 'barlines'; }
static get type() {
return {
SINGLE: 1,
DOUBLE: 2,
END: 3,
REPEAT_BEGIN: 4,
REPEAT_END: 5,
REPEAT_BOTH: 6,
NONE: 7,
};
}
/**
* @constructor
*/
constructor(type) {
super();
this.attrs.type = 'Barline';
this.thickness = Flow.STAVE_LINE_THICKNESS;
const TYPE = Barline.type;
this.widths = {};
this.widths[TYPE.SINGLE] = 5;
this.widths[TYPE.DOUBLE] = 5;
this.widths[TYPE.END] = 5;
this.widths[TYPE.REPEAT_BEGIN] = 5;
this.widths[TYPE.REPEAT_END] = 5;
this.widths[TYPE.REPEAT_BOTH] = 5;
this.widths[TYPE.NONE] = 5;
this.paddings = {};
this.paddings[TYPE.SINGLE] = 0;
this.paddings[TYPE.DOUBLE] = 0;
this.paddings[TYPE.END] = 0;
this.paddings[TYPE.REPEAT_BEGIN] = 15;
this.paddings[TYPE.REPEAT_END] = 15;
this.paddings[TYPE.REPEAT_BOTH] = 15;
this.paddings[TYPE.NONE] = 0;
this.setPosition(StaveModifier.Position.BEGIN);
this.setType(type);
}
getCategory() { return Barline.CATEGORY; }
getType() { return this.type; }
setType(type) {
this.type = type;
this.setWidth(this.widths[this.type]);
this.setPadding(this.paddings[this.type]);
return this;
}
Draw barlines
draw(stave) {
stave.checkContext();
switch (this.type) {
case Barline.type.SINGLE:
this.drawVerticalBar(stave, this.x, false);
break;
case Barline.type.DOUBLE:
this.drawVerticalBar(stave, this.x, true);
break;
case Barline.type.END:
this.drawVerticalEndBar(stave, this.x);
break;
case Barline.type.REPEAT_BEGIN:
If the barline is shifted over (in front of clef/time/key) Draw vertical bar at the beginning.
this.drawRepeatBar(stave, this.x, true);
if (stave.getX() !== this.x) {
this.drawVerticalBar(stave, stave.getX());
}
break;
case Barline.type.REPEAT_END:
this.drawRepeatBar(stave, this.x, false);
break;
case Barline.type.REPEAT_BOTH:
this.drawRepeatBar(stave, this.x, false);
this.drawRepeatBar(stave, this.x, true);
break;
default:
Default is NONE, so nothing to draw
break;
}
}
drawVerticalBar(stave, x, double_bar) {
stave.checkContext();
const topY = stave.getTopLineTopY();
const botY = stave.getBottomLineBottomY();
if (double_bar) {
stave.context.fillRect(x - 3, topY, 1, botY - topY);
}
stave.context.fillRect(x, topY, 1, botY - topY);
}
drawVerticalEndBar(stave, x) {
stave.checkContext();
const topY = stave.getTopLineTopY();
const botY = stave.getBottomLineBottomY();
stave.context.fillRect(x - 5, topY, 1, botY - topY);
stave.context.fillRect(x - 2, topY, 3, botY - topY);
}
drawRepeatBar(stave, x, begin) {
stave.checkContext();
const topY = stave.getTopLineTopY();
const botY = stave.getBottomLineBottomY();
let x_shift = 3;
if (!begin) {
x_shift = -5;
}
stave.context.fillRect(x + x_shift, topY, 1, botY - topY);
stave.context.fillRect(x - 2, topY, 3, botY - topY);
const dot_radius = 2;
Shift dots left or right
if (begin) {
x_shift += 4;
} else {
x_shift -= 4;
}
const dot_x = (x + x_shift) + (dot_radius / 2);
calculate the y offset based on number of stave lines
let y_offset = (stave.getNumLines() - 1) * stave.getSpacingBetweenLines();
y_offset = (y_offset / 2) - (stave.getSpacingBetweenLines() / 2);
let dot_y = topY + y_offset + (dot_radius / 2);
draw the top repeat dot
stave.context.beginPath();
stave.context.arc(dot_x, dot_y, dot_radius, 0, Math.PI * 2, false);
stave.context.fill();
draw the bottom repeat dot
dot_y += stave.getSpacingBetweenLines();
stave.context.beginPath();
stave.context.arc(dot_x, dot_y, dot_radius, 0, Math.PI * 2, false);
stave.context.fill();
}
}