vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature
1,199 lines (864 loc) • 61.9 kB
HTML
<!DOCTYPE html>
<html>
<head>
<title>stave.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div class="container">
<div class="page">
<div class="header">
<h1>stave.js</h1>
<div class="toc">
<h3>Table of Contents</h3>
<ol>
<li>
<a class="source" href="accidental.html">
accidental.js
</a>
</li>
<li>
<a class="source" href="annotation.html">
annotation.js
</a>
</li>
<li>
<a class="source" href="articulation.html">
articulation.js
</a>
</li>
<li>
<a class="source" href="barnote.html">
barnote.js
</a>
</li>
<li>
<a class="source" href="beam.html">
beam.js
</a>
</li>
<li>
<a class="source" href="bend.html">
bend.js
</a>
</li>
<li>
<a class="source" href="boundingbox.html">
boundingbox.js
</a>
</li>
<li>
<a class="source" href="boundingboxcomputation.html">
boundingboxcomputation.js
</a>
</li>
<li>
<a class="source" href="canvascontext.html">
canvascontext.js
</a>
</li>
<li>
<a class="source" href="clef.html">
clef.js
</a>
</li>
<li>
<a class="source" href="clefnote.html">
clefnote.js
</a>
</li>
<li>
<a class="source" href="crescendo.html">
crescendo.js
</a>
</li>
<li>
<a class="source" href="curve.html">
curve.js
</a>
</li>
<li>
<a class="source" href="dot.html">
dot.js
</a>
</li>
<li>
<a class="source" href="easyscore.html">
easyscore.js
</a>
</li>
<li>
<a class="source" href="element.html">
element.js
</a>
</li>
<li>
<a class="source" href="factory.html">
factory.js
</a>
</li>
<li>
<a class="source" href="formatter.html">
formatter.js
</a>
</li>
<li>
<a class="source" href="fraction.html">
fraction.js
</a>
</li>
<li>
<a class="source" href="frethandfinger.html">
frethandfinger.js
</a>
</li>
<li>
<a class="source" href="ghostnote.html">
ghostnote.js
</a>
</li>
<li>
<a class="source" href="glyph.html">
glyph.js
</a>
</li>
<li>
<a class="source" href="glyphnote.html">
glyphnote.js
</a>
</li>
<li>
<a class="source" href="gracenote.html">
gracenote.js
</a>
</li>
<li>
<a class="source" href="gracenotegroup.html">
gracenotegroup.js
</a>
</li>
<li>
<a class="source" href="gracetabnote.html">
gracetabnote.js
</a>
</li>
<li>
<a class="source" href="index.html">
index.js
</a>
</li>
<li>
<a class="source" href="keymanager.html">
keymanager.js
</a>
</li>
<li>
<a class="source" href="keysignature.html">
keysignature.js
</a>
</li>
<li>
<a class="source" href="keysignote.html">
keysignote.js
</a>
</li>
<li>
<a class="source" href="modifier.html">
modifier.js
</a>
</li>
<li>
<a class="source" href="modifiercontext.html">
modifiercontext.js
</a>
</li>
<li>
<a class="source" href="multimeasurerest.html">
multimeasurerest.js
</a>
</li>
<li>
<a class="source" href="music.html">
music.js
</a>
</li>
<li>
<a class="source" href="note.html">
note.js
</a>
</li>
<li>
<a class="source" href="notehead.html">
notehead.js
</a>
</li>
<li>
<a class="source" href="notesubgroup.html">
notesubgroup.js
</a>
</li>
<li>
<a class="source" href="ornament.html">
ornament.js
</a>
</li>
<li>
<a class="source" href="parser.html">
parser.js
</a>
</li>
<li>
<a class="source" href="pedalmarking.html">
pedalmarking.js
</a>
</li>
<li>
<a class="source" href="raphaelcontext.html">
raphaelcontext.js
</a>
</li>
<li>
<a class="source" href="registry.html">
registry.js
</a>
</li>
<li>
<a class="source" href="renderer.html">
renderer.js
</a>
</li>
<li>
<a class="source" href="repeatnote.html">
repeatnote.js
</a>
</li>
<li>
<a class="source" href="smufl.html">
smufl.js
</a>
</li>
<li>
<a class="source" href="stave.html">
stave.js
</a>
</li>
<li>
<a class="source" href="stavebarline.html">
stavebarline.js
</a>
</li>
<li>
<a class="source" href="staveconnector.html">
staveconnector.js
</a>
</li>
<li>
<a class="source" href="stavehairpin.html">
stavehairpin.js
</a>
</li>
<li>
<a class="source" href="staveline.html">
staveline.js
</a>
</li>
<li>
<a class="source" href="stavemodifier.html">
stavemodifier.js
</a>
</li>
<li>
<a class="source" href="stavenote.html">
stavenote.js
</a>
</li>
<li>
<a class="source" href="staverepetition.html">
staverepetition.js
</a>
</li>
<li>
<a class="source" href="stavesection.html">
stavesection.js
</a>
</li>
<li>
<a class="source" href="stavetempo.html">
stavetempo.js
</a>
</li>
<li>
<a class="source" href="stavetext.html">
stavetext.js
</a>
</li>
<li>
<a class="source" href="stavetie.html">
stavetie.js
</a>
</li>
<li>
<a class="source" href="stavevolta.html">
stavevolta.js
</a>
</li>
<li>
<a class="source" href="stem.html">
stem.js
</a>
</li>
<li>
<a class="source" href="stemmablenote.html">
stemmablenote.js
</a>
</li>
<li>
<a class="source" href="stringnumber.html">
stringnumber.js
</a>
</li>
<li>
<a class="source" href="strokes.html">
strokes.js
</a>
</li>
<li>
<a class="source" href="svgcontext.html">
svgcontext.js
</a>
</li>
<li>
<a class="source" href="system.html">
system.js
</a>
</li>
<li>
<a class="source" href="tables.html">
tables.js
</a>
</li>
<li>
<a class="source" href="tabnote.html">
tabnote.js
</a>
</li>
<li>
<a class="source" href="tabslide.html">
tabslide.js
</a>
</li>
<li>
<a class="source" href="tabstave.html">
tabstave.js
</a>
</li>
<li>
<a class="source" href="tabtie.html">
tabtie.js
</a>
</li>
<li>
<a class="source" href="textbracket.html">
textbracket.js
</a>
</li>
<li>
<a class="source" href="textdynamics.html">
textdynamics.js
</a>
</li>
<li>
<a class="source" href="textnote.html">
textnote.js
</a>
</li>
<li>
<a class="source" href="tickable.html">
tickable.js
</a>
</li>
<li>
<a class="source" href="tickcontext.html">
tickcontext.js
</a>
</li>
<li>
<a class="source" href="timesignature.html">
timesignature.js
</a>
</li>
<li>
<a class="source" href="timesignote.html">
timesignote.js
</a>
</li>
<li>
<a class="source" href="tremolo.html">
tremolo.js
</a>
</li>
<li>
<a class="source" href="tuning.html">
tuning.js
</a>
</li>
<li>
<a class="source" href="tuplet.html">
tuplet.js
</a>
</li>
<li>
<a class="source" href="vex.html">
vex.js
</a>
</li>
<li>
<a class="source" href="vibrato.html">
vibrato.js
</a>
</li>
<li>
<a class="source" href="vibratobracket.html">
vibratobracket.js
</a>
</li>
<li>
<a class="source" href="voice.html">
voice.js
</a>
</li>
<li>
<a class="source" href="voicegroup.html">
voicegroup.js
</a>
</li>
</ol>
</div>
</div>
<p><a href="http://vexflow.com">VexFlow</a> - Copyright (c) Mohit Muthanna 2010.</p>
<div class='highlight'><pre>
<span class="hljs-keyword">import</span> { Vex } <span class="hljs-keyword">from</span> <span class="hljs-string">'./vex'</span>;
<span class="hljs-keyword">import</span> { Element } <span class="hljs-keyword">from</span> <span class="hljs-string">'./element'</span>;
<span class="hljs-keyword">import</span> { Flow } <span class="hljs-keyword">from</span> <span class="hljs-string">'./tables'</span>;
<span class="hljs-keyword">import</span> { Barline } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavebarline'</span>;
<span class="hljs-keyword">import</span> { StaveModifier } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavemodifier'</span>;
<span class="hljs-keyword">import</span> { Repetition } <span class="hljs-keyword">from</span> <span class="hljs-string">'./staverepetition'</span>;
<span class="hljs-keyword">import</span> { StaveSection } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavesection'</span>;
<span class="hljs-keyword">import</span> { StaveTempo } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavetempo'</span>;
<span class="hljs-keyword">import</span> { StaveText } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavetext'</span>;
<span class="hljs-keyword">import</span> { BoundingBox } <span class="hljs-keyword">from</span> <span class="hljs-string">'./boundingbox'</span>;
<span class="hljs-keyword">import</span> { Clef } <span class="hljs-keyword">from</span> <span class="hljs-string">'./clef'</span>;
<span class="hljs-keyword">import</span> { KeySignature } <span class="hljs-keyword">from</span> <span class="hljs-string">'./keysignature'</span>;
<span class="hljs-keyword">import</span> { TimeSignature } <span class="hljs-keyword">from</span> <span class="hljs-string">'./timesignature'</span>;
<span class="hljs-keyword">import</span> { Volta } <span class="hljs-keyword">from</span> <span class="hljs-string">'./stavevolta'</span>;
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stave</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Element</span> </span>{
<span class="hljs-keyword">constructor</span>(x, y, width, options) {
<span class="hljs-keyword">super</span>();
<span class="hljs-keyword">this</span>.setAttribute(<span class="hljs-string">'type'</span>, <span class="hljs-string">'Stave'</span>);
<span class="hljs-keyword">this</span>.x = x;
<span class="hljs-keyword">this</span>.y = y;
<span class="hljs-keyword">this</span>.width = width;
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.start_x = x + <span class="hljs-number">5</span>;
<span class="hljs-keyword">this</span>.end_x = x + width;
<span class="hljs-keyword">this</span>.modifiers = []; <span class="hljs-comment">// stave modifiers (clef, key, time, barlines, coda, segno, etc.)</span>
<span class="hljs-keyword">this</span>.measure = <span class="hljs-number">0</span>;
<span class="hljs-keyword">this</span>.clef = <span class="hljs-string">'treble'</span>;
<span class="hljs-keyword">this</span>.endClef = <span class="hljs-literal">undefined</span>;
<span class="hljs-keyword">this</span>.font = {
<span class="hljs-attr">family</span>: <span class="hljs-string">'sans-serif'</span>,
<span class="hljs-attr">size</span>: <span class="hljs-number">8</span>,
<span class="hljs-attr">weight</span>: <span class="hljs-string">''</span>,
};
<span class="hljs-keyword">this</span>.options = {
<span class="hljs-attr">vertical_bar_width</span>: <span class="hljs-number">10</span>, <span class="hljs-comment">// Width around vertical bar end-marker</span>
glyph_spacing_px: <span class="hljs-number">10</span>,
<span class="hljs-attr">num_lines</span>: <span class="hljs-number">5</span>,
<span class="hljs-attr">fill_style</span>: <span class="hljs-string">'#999999'</span>,
<span class="hljs-attr">left_bar</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// draw vertical bar on left</span>
right_bar: <span class="hljs-literal">true</span>, <span class="hljs-comment">// draw vertical bar on right</span>
spacing_between_lines_px: <span class="hljs-number">10</span>, <span class="hljs-comment">// in pixels</span>
space_above_staff_ln: <span class="hljs-number">4</span>, <span class="hljs-comment">// in staff lines</span>
space_below_staff_ln: <span class="hljs-number">4</span>, <span class="hljs-comment">// in staff lines</span>
top_text_position: <span class="hljs-number">1</span>, <span class="hljs-comment">// in staff lines</span>
};
<span class="hljs-keyword">this</span>.bounds = { <span class="hljs-attr">x</span>: <span class="hljs-keyword">this</span>.x, <span class="hljs-attr">y</span>: <span class="hljs-keyword">this</span>.y, <span class="hljs-attr">w</span>: <span class="hljs-keyword">this</span>.width, <span class="hljs-attr">h</span>: <span class="hljs-number">0</span> };
Vex.Merge(<span class="hljs-keyword">this</span>.options, options);
<span class="hljs-keyword">this</span>.resetLines();
<span class="hljs-keyword">const</span> BARTYPE = Barline.type;</pre></div>
<p>beg bar</p>
<div class='highlight'><pre> <span class="hljs-keyword">this</span>.addModifier(<span class="hljs-keyword">new</span> Barline(<span class="hljs-keyword">this</span>.options.left_bar ? BARTYPE.SINGLE : BARTYPE.NONE));</pre></div>
<p>end bar</p>
<div class='highlight'><pre> <span class="hljs-keyword">this</span>.addEndModifier(<span class="hljs-keyword">new</span> Barline(<span class="hljs-keyword">this</span>.options.right_bar ? BARTYPE.SINGLE : BARTYPE.NONE));
}
space(spacing) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.options.spacing_between_lines_px * spacing; }
resetLines() {
<span class="hljs-keyword">this</span>.options.line_config = [];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-keyword">this</span>.options.num_lines; i++) {
<span class="hljs-keyword">this</span>.options.line_config.push({ <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span> });
}
<span class="hljs-keyword">this</span>.height = (<span class="hljs-keyword">this</span>.options.num_lines + <span class="hljs-keyword">this</span>.options.space_above_staff_ln) *
<span class="hljs-keyword">this</span>.options.spacing_between_lines_px;
<span class="hljs-keyword">this</span>.options.bottom_text_position = <span class="hljs-keyword">this</span>.options.num_lines;
}
getOptions() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.options; }
setNoteStartX(x) {
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.formatted) <span class="hljs-keyword">this</span>.format();
<span class="hljs-keyword">this</span>.start_x = x;
<span class="hljs-keyword">const</span> begBarline = <span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">0</span>];
begBarline.setX(<span class="hljs-keyword">this</span>.start_x - begBarline.getWidth());
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
getNoteStartX() {
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.formatted) <span class="hljs-keyword">this</span>.format();
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.start_x;
}
getNoteEndX() {
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.formatted) <span class="hljs-keyword">this</span>.format();
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.end_x;
}
getTieStartX() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.start_x; }
getTieEndX() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.x + <span class="hljs-keyword">this</span>.width; }
getX() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.x; }
getNumLines() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.options.num_lines; }
setNumLines(lines) {
<span class="hljs-keyword">this</span>.options.num_lines = <span class="hljs-built_in">parseInt</span>(lines, <span class="hljs-number">10</span>);
<span class="hljs-keyword">this</span>.resetLines();
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setY(y) { <span class="hljs-keyword">this</span>.y = y; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }
getTopLineTopY() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(<span class="hljs-number">0</span>) - (Flow.STAVE_LINE_THICKNESS / <span class="hljs-number">2</span>);
}
getBottomLineBottomY() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(<span class="hljs-keyword">this</span>.getNumLines() - <span class="hljs-number">1</span>) + (Flow.STAVE_LINE_THICKNESS / <span class="hljs-number">2</span>);
}
setX(x) {
<span class="hljs-keyword">const</span> shift = x - <span class="hljs-keyword">this</span>.x;
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.x = x;
<span class="hljs-keyword">this</span>.start_x += shift;
<span class="hljs-keyword">this</span>.end_x += shift;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-keyword">this</span>.modifiers.length; i++) {
<span class="hljs-keyword">const</span> mod = <span class="hljs-keyword">this</span>.modifiers[i];
<span class="hljs-keyword">if</span> (mod.x !== <span class="hljs-literal">undefined</span>) {
mod.x += shift;
}
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setWidth(width) {
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.width = width;
<span class="hljs-keyword">this</span>.end_x = <span class="hljs-keyword">this</span>.x + width;</pre></div>
<p>reset the x position of the end barline (TODO(0xfe): This makes no sense)
this.modifiers[1].setX(this.end_x);</p>
<div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
getWidth() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.width;
}
getStyle() {
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">fillStyle</span>: <span class="hljs-keyword">this</span>.options.fill_style,
<span class="hljs-attr">strokeStyle</span>: <span class="hljs-keyword">this</span>.options.fill_style, <span class="hljs-comment">// yes, this is correct for legacy compatibility</span>
lineWidth: Flow.STAVE_LINE_THICKNESS, ...this.style || {}
};
}
setMeasure(measure) { <span class="hljs-keyword">this</span>.measure = measure; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }
<span class="hljs-comment">/**
* Gets the pixels to shift from the beginning of the stave
* following the modifier at the provided index
* @param {Number} index The index from which to determine the shift
* @return {Number} The amount of pixels shifted
*/</span>
getModifierXShift(index = <span class="hljs-number">0</span>) {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> index !== <span class="hljs-string">'number'</span>) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Vex.RERR(<span class="hljs-string">'InvalidIndex'</span>, <span class="hljs-string">'Must be of number type'</span>);
}
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.formatted) <span class="hljs-keyword">this</span>.format();
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.getModifiers(StaveModifier.Position.BEGIN).length === <span class="hljs-number">1</span>) {
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
<span class="hljs-keyword">let</span> start_x = <span class="hljs-keyword">this</span>.start_x - <span class="hljs-keyword">this</span>.x;
<span class="hljs-keyword">const</span> begBarline = <span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">0</span>];
<span class="hljs-keyword">if</span> (begBarline.getType() === Barline.type.REPEAT_BEGIN && start_x > begBarline.getWidth()) {
start_x -= begBarline.getWidth();
}
<span class="hljs-keyword">return</span> start_x;
}</pre></div>
<p>Coda & Segno Symbol functions</p>
<div class='highlight'><pre> setRepetitionTypeLeft(type, y) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> Repetition(type, <span class="hljs-keyword">this</span>.x, y));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setRepetitionTypeRight(type, y) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> Repetition(type, <span class="hljs-keyword">this</span>.x, y));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Volta functions</p>
<div class='highlight'><pre> setVoltaType(type, number_t, y) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> Volta(type, number_t, <span class="hljs-keyword">this</span>.x, y));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Section functions</p>
<div class='highlight'><pre> setSection(section, y) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> StaveSection(section, <span class="hljs-keyword">this</span>.x, y));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Tempo functions</p>
<div class='highlight'><pre> setTempo(tempo, y) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> StaveTempo(tempo, <span class="hljs-keyword">this</span>.x, y));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Text functions</p>
<div class='highlight'><pre> setText(text, position, options) {
<span class="hljs-keyword">this</span>.modifiers.push(<span class="hljs-keyword">new</span> StaveText(text, position, options));
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
getHeight() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.height;
}
getSpacingBetweenLines() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.options.spacing_between_lines_px;
}
getBoundingBox() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BoundingBox(<span class="hljs-keyword">this</span>.x, <span class="hljs-keyword">this</span>.y, <span class="hljs-keyword">this</span>.width, <span class="hljs-keyword">this</span>.getBottomY() - <span class="hljs-keyword">this</span>.y);
}
getBottomY() {
<span class="hljs-keyword">const</span> options = <span class="hljs-keyword">this</span>.options;
<span class="hljs-keyword">const</span> spacing = options.spacing_between_lines_px;
<span class="hljs-keyword">const</span> score_bottom = <span class="hljs-keyword">this</span>.getYForLine(options.num_lines) +
(options.space_below_staff_ln * spacing);
<span class="hljs-keyword">return</span> score_bottom;
}
getBottomLineY() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(<span class="hljs-keyword">this</span>.options.num_lines);
}</pre></div>
<p>This returns the y for the <em>center</em> of a staff line</p>
<div class='highlight'><pre> getYForLine(line) {
<span class="hljs-keyword">const</span> options = <span class="hljs-keyword">this</span>.options;
<span class="hljs-keyword">const</span> spacing = options.spacing_between_lines_px;
<span class="hljs-keyword">const</span> headroom = options.space_above_staff_ln;
<span class="hljs-keyword">const</span> y = <span class="hljs-keyword">this</span>.y + (line * spacing) + (headroom * spacing);
<span class="hljs-keyword">return</span> y;
}
getLineForY(y) {</pre></div>
<p>Does the reverse of getYForLine - somewhat dumb and just calls
getYForLine until the right value is reaches</p>
<div class='highlight'><pre>
<span class="hljs-keyword">const</span> options = <span class="hljs-keyword">this</span>.options;
<span class="hljs-keyword">const</span> spacing = options.spacing_between_lines_px;
<span class="hljs-keyword">const</span> headroom = options.space_above_staff_ln;
<span class="hljs-keyword">return</span> ((y - <span class="hljs-keyword">this</span>.y) / spacing) - headroom;
}
getYForTopText(line) {
<span class="hljs-keyword">const</span> l = line || <span class="hljs-number">0</span>;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(-l - <span class="hljs-keyword">this</span>.options.top_text_position);
}
getYForBottomText(line) {
<span class="hljs-keyword">const</span> l = line || <span class="hljs-number">0</span>;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(<span class="hljs-keyword">this</span>.options.bottom_text_position + l);
}
getYForNote(line) {
<span class="hljs-keyword">const</span> options = <span class="hljs-keyword">this</span>.options;
<span class="hljs-keyword">const</span> spacing = options.spacing_between_lines_px;
<span class="hljs-keyword">const</span> headroom = options.space_above_staff_ln;
<span class="hljs-keyword">const</span> y = <span class="hljs-keyword">this</span>.y + (headroom * spacing) + (<span class="hljs-number">5</span> * spacing) - (line * spacing);
<span class="hljs-keyword">return</span> y;
}
getYForGlyphs() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getYForLine(<span class="hljs-number">3</span>);
}</pre></div>
<p>This method adds a stave modifier to the stave. Note that the first two
modifiers (BarLines) are automatically added upon construction.</p>
<div class='highlight'><pre> addModifier(modifier, position) {
<span class="hljs-keyword">if</span> (position !== <span class="hljs-literal">undefined</span>) {
modifier.setPosition(position);
}
modifier.setStave(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.modifiers.push(modifier);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addEndModifier(modifier) {
<span class="hljs-keyword">this</span>.addModifier(modifier, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Bar Line functions</p>
<div class='highlight'><pre> setBegBarType(type) {</pre></div>
<p>Only valid bar types at beginning of stave is none, single or begin repeat</p>
<div class='highlight'><pre> <span class="hljs-keyword">const</span> { SINGLE, REPEAT_BEGIN, NONE } = Barline.type;
<span class="hljs-keyword">if</span> (type === SINGLE || type === REPEAT_BEGIN || type === NONE) {
<span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">0</span>].setType(type);
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setEndBarType(type) {</pre></div>
<p>Repeat end not valid at end of stave</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> (type !== Barline.type.REPEAT_BEGIN) {
<span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">1</span>].setType(type);
<span class="hljs-keyword">this</span>.formatted = <span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setClef(clefSpec, size, annotation, position) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span>) {
position = StaveModifier.Position.BEGIN;
}
<span class="hljs-keyword">if</span> (position === StaveModifier.Position.END) {
<span class="hljs-keyword">this</span>.endClef = clefSpec;
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">this</span>.clef = clefSpec;
}
<span class="hljs-keyword">const</span> clefs = <span class="hljs-keyword">this</span>.getModifiers(position, Clef.CATEGORY);
<span class="hljs-keyword">if</span> (clefs.length === <span class="hljs-number">0</span>) {
<span class="hljs-keyword">this</span>.addClef(clefSpec, size, annotation, position);
} <span class="hljs-keyword">else</span> {
clefs[<span class="hljs-number">0</span>].setType(clefSpec, size, annotation);
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setEndClef(clefSpec, size, annotation) {
<span class="hljs-keyword">this</span>.setClef(clefSpec, size, annotation, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setKeySignature(keySpec, cancelKeySpec, position) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span>) {
position = StaveModifier.Position.BEGIN;
}
<span class="hljs-keyword">const</span> keySignatures = <span class="hljs-keyword">this</span>.getModifiers(position, KeySignature.CATEGORY);
<span class="hljs-keyword">if</span> (keySignatures.length === <span class="hljs-number">0</span>) {
<span class="hljs-keyword">this</span>.addKeySignature(keySpec, cancelKeySpec, position);
} <span class="hljs-keyword">else</span> {
keySignatures[<span class="hljs-number">0</span>].setKeySig(keySpec, cancelKeySpec);
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setEndKeySignature(keySpec, cancelKeySpec) {
<span class="hljs-keyword">this</span>.setKeySignature(keySpec, cancelKeySpec, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setTimeSignature(timeSpec, customPadding, position) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span>) {
position = StaveModifier.Position.BEGIN;
}
<span class="hljs-keyword">const</span> timeSignatures = <span class="hljs-keyword">this</span>.getModifiers(position, TimeSignature.CATEGORY);
<span class="hljs-keyword">if</span> (timeSignatures.length === <span class="hljs-number">0</span>) {
<span class="hljs-keyword">this</span>.addTimeSignature(timeSpec, customPadding, position);
} <span class="hljs-keyword">else</span> {
timeSignatures[<span class="hljs-number">0</span>].setTimeSig(timeSpec);
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
setEndTimeSignature(timeSpec, customPadding) {
<span class="hljs-keyword">this</span>.setTimeSignature(timeSpec, customPadding, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addKeySignature(keySpec, cancelKeySpec, position) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span>) {
position = StaveModifier.Position.BEGIN;
}
<span class="hljs-keyword">this</span>.addModifier(<span class="hljs-keyword">new</span> KeySignature(keySpec, cancelKeySpec)
.setPosition(position), position);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addClef(clef, size, annotation, position) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span> || position === StaveModifier.Position.BEGIN) {
<span class="hljs-keyword">this</span>.clef = clef;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (position === StaveModifier.Position.END) {
<span class="hljs-keyword">this</span>.endClef = clef;
}
<span class="hljs-keyword">this</span>.addModifier(<span class="hljs-keyword">new</span> Clef(clef, size, annotation), position);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addEndClef(clef, size, annotation) {
<span class="hljs-keyword">this</span>.addClef(clef, size, annotation, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addTimeSignature(timeSpec, customPadding, position) {
<span class="hljs-keyword">this</span>.addModifier(<span class="hljs-keyword">new</span> TimeSignature(timeSpec, customPadding), position);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
addEndTimeSignature(timeSpec, customPadding) {
<span class="hljs-keyword">this</span>.addTimeSignature(timeSpec, customPadding, StaveModifier.Position.END);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}</pre></div>
<p>Deprecated</p>
<div class='highlight'><pre> addTrebleGlyph() {
<span class="hljs-keyword">this</span>.addClef(<span class="hljs-string">'treble'</span>);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
getModifiers(position, category) {
<span class="hljs-keyword">if</span> (position === <span class="hljs-literal">undefined</span> && category === <span class="hljs-literal">undefined</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.modifiers;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.modifiers.filter(<span class="hljs-function"><span class="hljs-params">modifier</span> =></span>
(position === <span class="hljs-literal">undefined</span> || position === modifier.getPosition()) &&
(category === <span class="hljs-literal">undefined</span> || category === modifier.getCategory())
);
}
sortByCategory(items, order) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = items.length - <span class="hljs-number">1</span>; i >= <span class="hljs-number">0</span>; i--) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j < i; j++) {
<span class="hljs-keyword">if</span> (order[items[j].getCategory()] > order[items[j + <span class="hljs-number">1</span>].getCategory()]) {
<span class="hljs-keyword">const</span> temp = items[j];
items[j] = items[j + <span class="hljs-number">1</span>];
items[j + <span class="hljs-number">1</span>] = temp;
}
}
}
}
format() {
<span class="hljs-keyword">const</span> begBarline = <span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">0</span>];
<span class="hljs-keyword">const</span> endBarline = <span class="hljs-keyword">this</span>.modifiers[<span class="hljs-number">1</span>];
<span class="hljs-keyword">const</span> begModifiers = <span class="hljs-keyword">this</span>.getModifiers(StaveModifier.Position.BEGIN);
<span class="hljs-keyword">const</span> endModifiers = <span class="hljs-keyword">this</span>.getModifiers(StaveModifier.Position.END);
<span class="hljs-keyword">this</span>.sortByCategory(begModifiers, {
<span class="hljs-attr">barlines</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">clefs</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">keysignatures</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">timesignatures</span>: <span class="hljs-number">3</span>,
});
<span class="hljs-keyword">this</span>.sortByCategory(endModifiers, {
<span class="hljs-attr">timesignatures</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">keysignatures</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">barlines</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">clefs</span>: <span class="hljs-number">3</span>,
});
<span class="hljs-keyword">if</span> (begModifiers.length > <span class="hljs-number">1</span> &&
begBarline.getType() === Barline.type.REPEAT_BEGIN) {
begModifiers.push(begModifiers.splice(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>)[<span class="hljs-number">0</span>]);
begModifiers.splice(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-keyword">new</span> Barline(Barline.type.SINGLE));
}
<span class="hljs-keyword">if</span> (endModifiers.indexOf(endBarline) > <span class="hljs-number">0</span>) {
endModifiers.splice(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-keyword">new</span> Barline(Barline.type.NONE));
}
<span class="hljs-keyword">let</span> width;
<span class="hljs-keyword">let</span> padding;
<span class="hljs-keyword">let</span> modifier;
<span class="hljs-keyword">let</span> offset = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> x = <span class="hljs-keyword">this</span>.x;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < begModifiers.length; i++) {
modifier = begModifiers[i];
padding = modifier.getPadding(i + offset);
width = modifier.getWidth();
x += padding;
modifier.setX(x);
x += width;
<span class="hljs-keyword">if</span> (padding + width === <span class="hljs-number">0</span>) offset--;
}
<span class="hljs-keyword">this</span>.start_x = x;
x = <span class="hljs-keyword">this</span>.x + <span class="hljs-keyword">this</span>.width;
<span class="hljs-keyword">const</span> widths = {
<span class="hljs-attr">left</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">right</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">paddingRight</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">paddingLeft</span>: <span class="hljs-number">0</span>,
};
<span class="hljs-keyword">let</span> lastBarlineIdx = <span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < endModifiers.length; i++) {
modifier = endModifiers[i];
lastBarlineIdx = (modifier.getCategory() === <span class="hljs-string">'barlines'</span>) ? i : lastBarlineIdx;
widths.right = <span class="hljs-number">0</span>;
widths.left = <span class="hljs-number">0</span>;
widths.paddingRight = <span class="hljs-number">0</span>;
widths.paddingLeft = <span class="hljs-number">0</span>;
<span class="hljs-keyword">const</span> layoutMetrics = modifier.getLayoutMetrics();
<span class="hljs-keyword">if</span> (layoutMetrics) {
<span class="hljs-keyword">if</span> (i !== <span class="hljs-number">0</span>) {