UNPKG

satie

Version:

A sheet music renderer for the web

188 lines (187 loc) 7.92 kB
/** * This file is part of Satie music engraver <https://github.com/jnetterf/satie>. * Copyright (C) Joshua Netterfield <joshua.ca> 2015 - present. * * Satie is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Satie is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Satie. If not, see <http://www.gnu.org/licenses/>. */ "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var musicxml_interfaces_1 = require("musicxml-interfaces"); var react_1 = require("react"); var lodash_1 = require("lodash"); var implAttributes_accidentalView_1 = require("./implAttributes_accidentalView"); var implAttributes_attributesData_1 = require("./implAttributes_attributesData"); var private_chordUtil_1 = require("./private_chordUtil"); var $AccidentalView = react_1.createFactory(implAttributes_accidentalView_1.default); // TODO: this almost looks like logic -- move. var sharps = { // "FCGDAEB" alto: [4.5, 3, 5, 3.5, 2, 4, 2.5], bass: [4, 2.5, 4.5, 3, 1.5, 3.5, 2], tenor: [2, 4, 2.5, 4.5, 3, 5, 3.5], treble: [5, 3.5, 5.5, 4, 2.5, 4.5, 3] }; var flats = { // "BEADGCF" alto: [2.5, 4, 2, 3.5, 1.5, 3, 1], bass: [2, 3.5, 1.5, 3, 1, 2.5, 0.5], tenor: [3.5, 5, 3, 4.5, 2.5, 4, 2], treble: [3, 4.5, 2.5, 4, 2, 3.5, 1.5] }; /** * Renders a key signature. */ var KeyView = (function (_super) { __extends(KeyView, _super); function KeyView() { return _super !== null && _super.apply(this, arguments) || this; } KeyView.prototype.render = function () { return react_1.DOM.g(null, lodash_1.map(this.getAccidentals(), function (accidental, idx) { return $AccidentalView({ key: idx, spec: accidental }); })); }; /** * Returns an array representing the position and glyphName of each accidental. */ KeyView.prototype.getAccidentals = function () { var _this = this; // TODO: this is expensive -- compute in attributes! var spec = this.props.spec; var clef = this.props.clef; var widths = implAttributes_attributesData_1.keyWidths(spec); var positions = []; var x = 0; if (spec.fifths) { var accCount = Math.min(7, Math.abs(spec.fifths)); var idxes_1 = lodash_1.times(accCount, function (i) { return (i + Math.max(0, Math.abs(spec.fifths) - 7)) % 7; }); for (var i = 0; i < idxes_1.length; ++i) { positions.push(x); x += widths[idxes_1[i]]; } return lodash_1.map(idxes_1, function (i) { return makeAccidentalFromSharps(idxes_1, i, spec.fifths >= 0); }); } for (var i = 0; i < widths.length; ++i) { positions.push(x); x += widths[i]; } if (spec.keySteps) { return lodash_1.map(spec.keySteps, function (keyStep, idx) { var keyAlters = spec.keyAlters[idx]; var hasOctave = spec.keyOctaves && spec.keyOctaves[idx]; var octave = hasOctave ? spec.keyOctaves[idx].octave : null; if (octave === null) { while (private_chordUtil_1.lineForClef_(keyStep, octave, _this.props.clef) < 2) { ++octave; } } var line = private_chordUtil_1.lineForClef_(keyStep, octave, _this.props.clef); var accidental = null; switch (keyAlters) { case "-2": accidental = musicxml_interfaces_1.MxmlAccidental.DoubleFlat; break; case "-1.5": accidental = musicxml_interfaces_1.MxmlAccidental.ThreeQuartersFlat; break; case "-1": accidental = musicxml_interfaces_1.MxmlAccidental.Flat; break; case "-0.5": accidental = musicxml_interfaces_1.MxmlAccidental.QuarterFlat; break; case "0": accidental = musicxml_interfaces_1.MxmlAccidental.Natural; break; case "0.5": accidental = musicxml_interfaces_1.MxmlAccidental.QuarterSharp; break; case "1": accidental = musicxml_interfaces_1.MxmlAccidental.Sharp; break; case "1.5": accidental = musicxml_interfaces_1.MxmlAccidental.ThreeQuartersSharp; break; case "2": accidental = musicxml_interfaces_1.MxmlAccidental.DoubleSharp; break; default: console.warn("Unknown accidental ", keyAlters); accidental = musicxml_interfaces_1.MxmlAccidental.Natural; } return { accidental: accidental, color: spec.color, defaultX: spec.defaultX + positions[idx], defaultY: spec.defaultY + (line - 3) * 10, relativeX: spec.relativeX, relativeY: (spec.relativeY || 0) }; }); } function makeAccidentalFromSharps(idxes, i, sharp) { var accidental; switch (true) { case (sharp && 7 + idxes[i] < spec.fifths): accidental = musicxml_interfaces_1.MxmlAccidental.DoubleSharp; break; case (sharp && 7 + idxes[i] >= spec.fifths): accidental = musicxml_interfaces_1.MxmlAccidental.Sharp; break; case (!sharp && (7 + idxes[i] < -spec.fifths)): accidental = musicxml_interfaces_1.MxmlAccidental.DoubleFlat; break; case (!sharp && (7 + idxes[i] >= -spec.fifths)): accidental = musicxml_interfaces_1.MxmlAccidental.Flat; break; default: throw new Error("Impossible!"); } var line = (sharp ? sharps : flats)[standardClef(clef)][idxes[i]]; return { accidental: accidental, color: spec.color, defaultX: spec.defaultX + positions[i], defaultY: spec.defaultY + (line - 3) * 10, relativeX: spec.relativeX, relativeY: (spec.relativeY || 0) }; } }; return KeyView; }(react_1.Component)); ; function standardClef(clef) { switch (true) { case (clef.sign === "G"): return "treble"; case (clef.sign === "F"): return "bass"; case (clef.sign === "C" && clef.line === 3): return "alto"; case (clef.sign === "C" && clef.line === 4): return "tenor"; default: console.warn("Invalid clef?"); return "treble"; } } ; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyView;