UNPKG

vexflow

Version:

A JavaScript library for rendering music notation and guitar tablature

869 lines (641 loc) 32 kB
<!DOCTYPE html> <html> <head> <title>multimeasurerest.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>multimeasurerest.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>VexFlow - Music Engraving for HTML5 Copyright Mohit Muthanna 2010</p> <p>This class implements multiple measure rests</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> { Flow } <span class="hljs-keyword">from</span> <span class="hljs-string">'./tables'</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> { Glyph } <span class="hljs-keyword">from</span> <span class="hljs-string">'./glyph'</span>; <span class="hljs-keyword">import</span> { NoteHead } <span class="hljs-keyword">from</span> <span class="hljs-string">'./notehead'</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> { TimeSignature } <span class="hljs-keyword">from</span> <span class="hljs-string">'./timesignature'</span>; <span class="hljs-keyword">let</span> semibrave_rest; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get_semibrave_rest</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">if</span> (!semibrave_rest) { <span class="hljs-keyword">const</span> notehead = <span class="hljs-keyword">new</span> NoteHead({ <span class="hljs-attr">duration</span>: <span class="hljs-string">'w'</span>, <span class="hljs-attr">note_type</span>: <span class="hljs-string">'r'</span> }); semibrave_rest = { <span class="hljs-attr">glyph_font_scale</span>: notehead.render_options.glyph_font_scale, <span class="hljs-attr">glyph_code</span>: notehead.glyph_code, <span class="hljs-attr">width</span>: notehead.getWidth(), }; } <span class="hljs-keyword">return</span> semibrave_rest; } <span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MultiMeasureRest</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Element</span> </span>{</pre></div> <p>Parameters:</p> <ul> <li><code>number_of_measures</code> - Number of measures.</li> <li><code>options</code> - The options object.<ul> <li><code>show_number</code> - Show number of measures string or not.</li> <li><code>number_line</code> - Staff line to render the number of measures string.</li> <li><code>number_glyph_point</code> - Size of the number of measures string glyphs.</li> <li><code>padding_left</code> - Left padding from stave x.</li> <li><code>padding_right</code> - Right padding from stave end x.</li> <li><code>line</code> - Staff line to render rest line or rest symbols.</li> <li><code>spacing_between_lines_px</code> - Spacing between staff lines to resolve serif height or {2-bar and 4-bar}rest symbol height.</li> <li><code>line_thickness</code> - Rest line thickness.</li> <li><code>serif_thickness</code> - Rest serif line thickness.</li> <li><code>use_symbols</code> - Use rest symbols or not.</li> <li><code>symbol_spacing</code> - Spacing between each rest symbol glyphs.</li> <li><code>semibrave_rest_glyph_scale</code> - Size of the semibrave(1-bar) rest symbol.</li> </ul> </li> </ul> <div class='highlight'><pre> <span class="hljs-keyword">constructor</span>(number_of_measures, options) { <span class="hljs-keyword">super</span>(); <span class="hljs-keyword">this</span>.setAttribute(<span class="hljs-string">'type'</span>, <span class="hljs-string">'MultiMeasureRest'</span>); <span class="hljs-keyword">const</span> point = <span class="hljs-keyword">this</span>.musicFont.lookupMetric(<span class="hljs-string">'digits.point'</span>); <span class="hljs-keyword">const</span> fontLineShift = <span class="hljs-keyword">this</span>.musicFont.lookupMetric(<span class="hljs-string">'digits.shiftLine'</span>, <span class="hljs-number">0</span>); <span class="hljs-keyword">this</span>.render_options = { <span class="hljs-attr">show_number</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">number_line</span>: <span class="hljs-number">-0.5</span>, <span class="hljs-attr">number_glyph_point</span>: point, <span class="hljs-comment">// same as TimeSignature.</span> padding_left: <span class="hljs-literal">undefined</span>, <span class="hljs-attr">padding_right</span>: <span class="hljs-literal">undefined</span>, <span class="hljs-attr">line</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">spacing_between_lines_px</span>: <span class="hljs-number">10</span>, <span class="hljs-comment">// same as Stave.</span> line_thickness: <span class="hljs-literal">undefined</span>, <span class="hljs-attr">serif_thickness</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">use_symbols</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">symbol_spacing</span>: <span class="hljs-literal">undefined</span>, <span class="hljs-comment">/* same as NoteHead. */</span> semibrave_rest_glyph_scale: Flow.DEFAULT_NOTATION_FONT_SCALE, }; Vex.Merge(<span class="hljs-keyword">this</span>.render_options, options); <span class="hljs-keyword">this</span>.render_options.number_line += fontLineShift; <span class="hljs-keyword">this</span>.number_of_measures = number_of_measures; <span class="hljs-keyword">this</span>.xs = { <span class="hljs-attr">left</span>: <span class="hljs-literal">NaN</span>, <span class="hljs-attr">right</span>: <span class="hljs-literal">NaN</span>, }; } getXs() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.xs; } setStave(stave) { <span class="hljs-keyword">this</span>.stave = stave; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; } getStave() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.stave; } drawLine(ctx, left, right, sbl) { <span class="hljs-keyword">const</span> y = <span class="hljs-keyword">this</span>.stave.getYForLine(<span class="hljs-keyword">this</span>.render_options.line); <span class="hljs-keyword">const</span> padding = (right - left) * <span class="hljs-number">0.1</span>; left += padding; right -= padding; <span class="hljs-keyword">const</span> serif = { <span class="hljs-attr">thickness</span>: <span class="hljs-keyword">this</span>.render_options.serif_thickness, <span class="hljs-attr">height</span>: sbl, }; <span class="hljs-keyword">let</span> lineThicknessHalf = sbl * <span class="hljs-number">0.25</span>; <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(<span class="hljs-keyword">this</span>.render_options.line_thickness)) { lineThicknessHalf = <span class="hljs-keyword">this</span>.render_options.line_thickness * <span class="hljs-number">0.5</span>; } ctx.save(); ctx.beginPath(); ctx.moveTo(left, y - sbl); ctx.lineTo(left + serif.thickness, y - sbl); ctx.lineTo(left + serif.thickness, y - lineThicknessHalf); ctx.lineTo(right - serif.thickness, y - lineThicknessHalf); ctx.lineTo(right - serif.thickness, y - sbl); ctx.lineTo(right, y - sbl); ctx.lineTo(right, y + sbl); ctx.lineTo(right - serif.thickness, y + sbl); ctx.lineTo(right - serif.thickness, y + lineThicknessHalf); ctx.lineTo(left + serif.thickness, y + lineThicknessHalf); ctx.lineTo(left + serif.thickness, y + sbl); ctx.lineTo(left, y + sbl); ctx.closePath(); ctx.fill(); } drawSymbols(ctx, left, right, sbl) { <span class="hljs-keyword">const</span> n4 = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-keyword">this</span>.number_of_measures / <span class="hljs-number">4</span>); <span class="hljs-keyword">const</span> n = <span class="hljs-keyword">this</span>.number_of_measures % <span class="hljs-number">4</span>; <span class="hljs-keyword">const</span> n2 = <span class="hljs-built_in">Math</span>.floor(n / <span class="hljs-number">2</span>); <span class="hljs-keyword">const</span> n1 = n % <span class="hljs-number">2</span>; <span class="hljs-keyword">const</span> semibrave_rest = get_semibrave_rest(); <span class="hljs-keyword">const</span> semibrave_rest_width = semibrave_rest.width * (<span class="hljs-keyword">this</span>.render_options.semibrave_rest_glyph_scale / semibrave_rest.glyph_font_scale); <span class="hljs-keyword">const</span> glyphs = { <span class="hljs-number">2</span>: { <span class="hljs-attr">width</span>: semibrave_rest_width * <span class="hljs-number">0.5</span>, <span class="hljs-attr">height</span>: sbl, }, <span class="hljs-number">1</span>: { <span class="hljs-attr">width</span>: semibrave_rest_width, }, }; <span class="hljs-keyword">let</span> spacing = semibrave_rest_width * <span class="hljs-number">1.35</span>; <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(<span class="hljs-keyword">this</span>.render_options.symbol_spacing)) { spacing = <span class="hljs-keyword">this</span>.render_options.symbol_spacing; } <span class="hljs-keyword">const</span> width = (n4 * glyphs[<span class="hljs-number">2</span>].width) + (n2 * glyphs[<span class="hljs-number">2</span>].width) + (n1 * glyphs[<span class="hljs-number">1</span>].width) + ((n4 + n2 + n1 - <span class="hljs-number">1</span>) * spacing); <span class="hljs-keyword">let</span> x = left + ((right - left) * <span class="hljs-number">0.5</span>) - (width * <span class="hljs-number">0.5</span>); <span class="hljs-keyword">const</span> yTop = <span class="hljs-keyword">this</span>.stave.getYForLine(<span class="hljs-keyword">this</span>.render_options.line - <span class="hljs-number">1</span>); <span class="hljs-keyword">const</span> yMiddle = <span class="hljs-keyword">this</span>.stave.getYForLine(<span class="hljs-keyword">this</span>.render_options.line); <span class="hljs-keyword">const</span> yBottom = <span class="hljs-keyword">this</span>.stave.getYForLine(<span class="hljs-keyword">this</span>.render_options.line + <span class="hljs-number">1</span>); ctx.save(); ctx.setStrokeStyle(<span class="hljs-string">'none'</span>); ctx.setLineWidth(<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 &lt; n4; ++i) { ctx.fillRect(x, yMiddle - glyphs[<span class="hljs-number">2</span>].height, glyphs[<span class="hljs-number">2</span>].width, glyphs[<span class="hljs-number">2</span>].height); ctx.fillRect(x, yBottom - glyphs[<span class="hljs-number">2</span>].height, glyphs[<span class="hljs-number">2</span>].width, glyphs[<span class="hljs-number">2</span>].height); x += glyphs[<span class="hljs-number">2</span>].width + spacing; } <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; n2; ++i) { ctx.fillRect(x, yMiddle - glyphs[<span class="hljs-number">2</span>].height, glyphs[<span class="hljs-number">2</span>].width, glyphs[<span class="hljs-number">2</span>].height); x += glyphs[<span class="hljs-number">2</span>].width + spacing; } <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; n1; ++i) { Glyph.renderGlyph(ctx, x, yTop, <span class="hljs-keyword">this</span>.render_options.semibrave_rest_glyph_scale, semibrave_rest.glyph_code); x += glyphs[<span class="hljs-number">1</span>].width + spacing; } ctx.restore(); } draw() { <span class="hljs-keyword">this</span>.checkContext(); <span class="hljs-keyword">this</span>.setRendered(); <span class="hljs-keyword">const</span> ctx = <span class="hljs-keyword">this</span>.context; <span class="hljs-keyword">const</span> stave = <span class="hljs-keyword">this</span>.stave; <span class="hljs-keyword">const</span> sbl = <span class="hljs-keyword">this</span>.render_options.spacing_between_lines_px; <span class="hljs-keyword">let</span> left = stave.getNoteStartX(); <span class="hljs-keyword">let</span> right = stave.getNoteEndX();</pre></div> <p>FIXME: getNoteStartX() returns x+5(barline width) and getNoteEndX() returns x + width(no barline width) by default. how to fix?</p> <div class='highlight'><pre> <span class="hljs-keyword">const</span> begModifiers = stave.getModifiers(StaveModifier.Position.BEGIN); <span class="hljs-keyword">if</span> (begModifiers.length === <span class="hljs-number">1</span> &amp;&amp; begModifiers[<span class="hljs-number">0</span>].getCategory() === <span class="hljs-string">'barlines'</span>) { left -= begModifiers[<span class="hljs-number">0</span>].getWidth(); } <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(<span class="hljs-keyword">this</span>.render_options.padding_left)) { left = stave.getX() + <span class="hljs-keyword">this</span>.render_options.padding_left; } <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(<span class="hljs-keyword">this</span>.render_options.padding_right)) { right = stave.getX() + stave.getWidth() - <span class="hljs-keyword">this</span>.render_options.padding_right; } <span class="hljs-keyword">this</span>.xs.left = left; <span class="hljs-keyword">this</span>.xs.right = right; <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.render_options.use_symbols) { <span class="hljs-keyword">this</span>.drawSymbols(ctx, left, right, sbl); } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">this</span>.drawLine(ctx, left, right, sbl); } <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.render_options.show_number) { <span class="hljs-keyword">const</span> timeSpec = <span class="hljs-string">'/'</span> + <span class="hljs-keyword">this</span>.number_of_measures; <span class="hljs-keyword">const</span> timeSig = <span class="hljs-keyword">new</span> TimeSignature(<span class="hljs-literal">null</span>, <span class="hljs-literal">undefined</span>, <span class="hljs-literal">false</span>); timeSig.point = <span class="hljs-keyword">this</span>.render_options.number_glyph_point; timeSig.setTimeSig(timeSpec); timeSig.setStave(stave); timeSig.x = left + ((right - left) * <span class="hljs-number">0.5</span>) - (timeSig.timeSig.glyph.getMetrics().width * <span class="hljs-number">0.5</span>); timeSig.bottomLine = <span class="hljs-keyword">this</span>.render_options.number_line; timeSig.setContext(ctx).draw(); } } }</pre></div> <div class="fleur">h</div> </div> </div> </body> </html>