vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature
769 lines (550 loc) • 27.9 kB
HTML
<html>
<head>
<title>tickcontext.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>tickcontext.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="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="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>
<h2 id="description">Description</h2>
<p>A formatter for abstract tickable objects, such as notes, chords,
tabs, etc.</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> { Tickable } <span class="hljs-keyword">from</span> <span class="hljs-string">'./tickable'</span>;
<span class="hljs-keyword">import</span> { Fraction } <span class="hljs-keyword">from</span> <span class="hljs-string">'./fraction'</span>;
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TickContext</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Tickable</span> </span>{
<span class="hljs-keyword">static</span> getNextContext(tContext) {
<span class="hljs-keyword">const</span> contexts = tContext.tContexts;
<span class="hljs-keyword">const</span> index = contexts.indexOf(tContext);
<span class="hljs-keyword">return</span> contexts[index + <span class="hljs-number">1</span>];
}
<span class="hljs-keyword">constructor</span>() {
<span class="hljs-keyword">super</span>();
<span class="hljs-keyword">this</span>.setAttribute(<span class="hljs-string">'type'</span>, <span class="hljs-string">'TickContext'</span>);
<span class="hljs-keyword">this</span>.currentTick = <span class="hljs-keyword">new</span> Fraction(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>);
<span class="hljs-keyword">this</span>.maxTicks = <span class="hljs-keyword">new</span> Fraction(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>);
<span class="hljs-keyword">this</span>.minTicks = <span class="hljs-literal">null</span>;
<span class="hljs-keyword">this</span>.padding = <span class="hljs-number">3</span>; <span class="hljs-comment">// padding on each side (width += padding * 2)</span>
<span class="hljs-keyword">this</span>.x = <span class="hljs-number">0</span>;
<span class="hljs-keyword">this</span>.xBase = <span class="hljs-number">0</span>; <span class="hljs-comment">// base x position without xOffset</span>
<span class="hljs-keyword">this</span>.xOffset = <span class="hljs-number">0</span>; <span class="hljs-comment">// xBase and xOffset are an alternative way to describe x (x = xB + xO)</span>
<span class="hljs-keyword">this</span>.tickables = []; <span class="hljs-comment">// Notes, tabs, chords, lyrics.</span>
<span class="hljs-keyword">this</span>.notePx = <span class="hljs-number">0</span>; <span class="hljs-comment">// width of widest note in this context</span>
<span class="hljs-keyword">this</span>.extraLeftPx = <span class="hljs-number">0</span>; <span class="hljs-comment">// Extra left pixels for modifers & displace notes</span>
<span class="hljs-keyword">this</span>.extraRightPx = <span class="hljs-number">0</span>; <span class="hljs-comment">// Extra right pixels for modifers & displace notes</span>
<span class="hljs-keyword">this</span>.tContexts = []; <span class="hljs-comment">// Parent array of tick contexts</span>
}
getX() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.x; }
setX(x) { <span class="hljs-keyword">this</span>.x = x; <span class="hljs-keyword">this</span>.xBase = x; <span class="hljs-keyword">this</span>.xOffset = <span class="hljs-number">0</span>; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }
getXBase() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.xBase; } <span class="hljs-comment">// use of xBase and xOffset is optional, avoids offset creep</span>
setXBase(xBase) { <span class="hljs-keyword">this</span>.xBase = xBase; <span class="hljs-keyword">this</span>.x = xBase + <span class="hljs-keyword">this</span>.xOffset; }
getXOffset() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.xOffset; }
setXOffset(xOffset) { <span class="hljs-keyword">this</span>.xOffset = xOffset; <span class="hljs-keyword">this</span>.x = <span class="hljs-keyword">this</span>.xBase + xOffset; }
getWidth() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.width + (<span class="hljs-keyword">this</span>.padding * <span class="hljs-number">2</span>); }
setPadding(padding) { <span class="hljs-keyword">this</span>.padding = padding; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }
getMaxTicks() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.maxTicks; }
getMinTicks() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.minTicks; }
getTickables() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.tickables; }
getCenterAlignedTickables() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.tickables.filter(<span class="hljs-function"><span class="hljs-params">tickable</span> =></span> tickable.isCenterAligned());
}</pre></div>
<p>Get widths context, note and left/right modifiers for formatting</p>
<div class='highlight'><pre> getMetrics() {
<span class="hljs-keyword">const</span> { width, notePx, extraLeftPx, extraRightPx } = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">return</span> { width, notePx, extraLeftPx, extraRightPx };
}
getCurrentTick() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.currentTick; }
setCurrentTick(tick) {
<span class="hljs-keyword">this</span>.currentTick = tick;
<span class="hljs-keyword">this</span>.preFormatted = <span class="hljs-literal">false</span>;
}</pre></div>
<h3 id="deprecated">DEPRECATED</h3>
<p>Get left & right pixels used for modifiers. THIS METHOD IS DEPRECATED. Use
the getMetrics() method instead!</p>
<div class='highlight'><pre> getExtraPx() {
<span class="hljs-keyword">let</span> left_shift = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> right_shift = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> extraLeftPx = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> extraRightPx = <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 < <span class="hljs-keyword">this</span>.tickables.length; i++) {
extraLeftPx = <span class="hljs-built_in">Math</span>.max(<span class="hljs-keyword">this</span>.tickables[i].extraLeftPx || <span class="hljs-number">0</span>, extraLeftPx);
extraRightPx = <span class="hljs-built_in">Math</span>.max(<span class="hljs-keyword">this</span>.tickables[i].extraRightPx || <span class="hljs-number">0</span>, extraRightPx);
<span class="hljs-keyword">const</span> mContext = <span class="hljs-keyword">this</span>.tickables[i].modifierContext;
<span class="hljs-keyword">if</span> (mContext && mContext != <span class="hljs-literal">null</span>) {
left_shift = <span class="hljs-built_in">Math</span>.max(left_shift, mContext.state.left_shift);
right_shift = <span class="hljs-built_in">Math</span>.max(right_shift, mContext.state.right_shift);
}
}
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">left</span>: left_shift,
<span class="hljs-attr">right</span>: right_shift,
<span class="hljs-attr">extraLeft</span>: extraLeftPx,
<span class="hljs-attr">extraRight</span>: extraRightPx,
};
}
addTickable(tickable) {
<span class="hljs-keyword">if</span> (!tickable) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Vex.RERR(<span class="hljs-string">'BadArgument'</span>, <span class="hljs-string">'Invalid tickable added.'</span>);
}
<span class="hljs-keyword">if</span> (!tickable.shouldIgnoreTicks()) {
<span class="hljs-keyword">this</span>.ignore_ticks = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">const</span> ticks = tickable.getTicks();
<span class="hljs-keyword">if</span> (ticks.greaterThan(<span class="hljs-keyword">this</span>.maxTicks)) {
<span class="hljs-keyword">this</span>.maxTicks = ticks.clone();
}
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.minTicks == <span class="hljs-literal">null</span>) {
<span class="hljs-keyword">this</span>.minTicks = ticks.clone();
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (ticks.lessThan(<span class="hljs-keyword">this</span>.minTicks)) {
<span class="hljs-keyword">this</span>.minTicks = ticks.clone();
}
}
tickable.setTickContext(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">this</span>.tickables.push(tickable);
<span class="hljs-keyword">this</span>.preFormatted = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
preFormat() {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.preFormatted) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
<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>.tickables.length; ++i) {
<span class="hljs-keyword">const</span> tickable = <span class="hljs-keyword">this</span>.tickables[i];
tickable.preFormat();
<span class="hljs-keyword">const</span> metrics = tickable.getMetrics();</pre></div>
<p>Maintain max extra pixels from all tickables in the context</p>
<div class='highlight'><pre> <span class="hljs-keyword">this</span>.extraLeftPx = <span class="hljs-built_in">Math</span>.max(<span class="hljs-keyword">this</span>.extraLeftPx, metrics.extraLeftPx + metrics.modLeftPx);
<span class="hljs-keyword">this</span>.extraRightPx = <span class="hljs-built_in">Math</span>.max(<span class="hljs-keyword">this</span>.extraRightPx, metrics.extraRightPx + metrics.modRightPx);</pre></div>
<p>Maintain the widest note for all tickables in the context</p>
<div class='highlight'><pre> <span class="hljs-keyword">this</span>.notePx = <span class="hljs-built_in">Math</span>.max(<span class="hljs-keyword">this</span>.notePx, metrics.noteWidth);</pre></div>
<p>Recalculate the tick context total width</p>
<div class='highlight'><pre> <span class="hljs-keyword">this</span>.width = <span class="hljs-keyword">this</span>.notePx + <span class="hljs-keyword">this</span>.extraLeftPx + <span class="hljs-keyword">this</span>.extraRightPx;
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
postFormat() {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.postFormatted) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">this</span>.postFormatted = <span class="hljs-literal">true</span>;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
}</pre></div>
<div class="fleur">h</div>
</div>
</div>
</body>
</html>