Browse Source

Merge pull request #183 from opensheetmusicdisplay/feature/InstrumentBrace

Added instrument brace/bracket
matt-uib 7 năm trước cách đây
mục cha
commit
3cf680e2e2

+ 3 - 3
demo/index.html

@@ -8,11 +8,11 @@
     <meta name="author" content="OpenSheetMusicDisplay contributors">
 
     <!-- Include opensheetmusicdisplay -->
-    <script src="osmd-debug.js"></script>
+    <!-- <script src="./osmd.js" type="text/javascript"></script> -->
 
     <!-- Include code and styles for this demo -->
-    <script src="demo.js"></script>
-    <link href="demo.css" media="all" rel="stylesheet"/>
+    <script src="./demo.js" type="text/javascript"></script>
+    <link href="./demo.css" media="all" rel="stylesheet"/>
     <link rel="icon" href="./favicon.ico?" type="image/x-icon"/>
 </head>
 <body>

+ 19 - 17
demo/demo.js → demo/index.js

@@ -1,11 +1,14 @@
+import { OSMD } from '../src/OSMD/OSMD';
+
 /*jslint browser:true */
 (function () {
     "use strict";
-    var OSMD;
+    var osmdObj;
     // The folder of the demo files
-    var folder = "sheets/",
+    var folder = "",
     // The available demos
         demos = {
+            "Beethoven - AnDieFerneGeliebte": "Beethoven_AnDieFerneGeliebte.xml",
             "M. Clementi - Sonatina Op.36 No.1 Pt.1": "MuzioClementi_SonatinaOpus36No1_Part1.xml",
             "M. Clementi - Sonatina Op.36 No.1 Pt.2": "MuzioClementi_SonatinaOpus36No1_Part2.xml",
             "M. Clementi - Sonatina Op.36 No.3 Pt.1": "MuzioClementi_SonatinaOpus36No3_Part1.xml",
@@ -19,7 +22,6 @@
             "S. Joplin - The Entertainer": "ScottJoplin_The_Entertainer.xml",
             "ActorPreludeSample": "ActorPreludeSample.xml",
             "an chloe - mozart": "an chloe - mozart.xml",
-            "Beethoven - AnDieFerneGeliebte": "AnDieFerneGeliebte_Beethoven.xml",
             "das veilchen - mozart": "das veilchen - mozart.xml",
             "Dichterliebe01": "Dichterliebe01.xml",
             "mandoline - debussy": "mandoline - debussy.xml",
@@ -89,8 +91,8 @@
         };
 
         // Create OSMD object and canvas
-        OSMD = new opensheetmusicdisplay.OSMD(canvas, false);
-        OSMD.setLogLevel('info');
+        osmdObj = new OSMD(canvas, false);
+        osmdObj.setLogLevel('info');
         document.body.appendChild(canvas);
 
         // Set resize event handler
@@ -102,7 +104,7 @@
                 var width = document.body.clientWidth;
                 canvas.width = width;
                 try {
-                OSMD.render();
+                osmdObj.render();
                 } catch (e) {}
                 enable();
             }
@@ -111,28 +113,28 @@
         window.addEventListener("keydown", function(e) {
             var event = window.event ? window.event : e;
             if (event.keyCode === 39) {
-                OSMD.cursor.next();
+                osmdObj.cursor.next();
             }
         });
         nextCursorBtn.addEventListener("click", function() {
-            OSMD.cursor.next();
+            osmdObj.cursor.next();
         });
         resetCursorBtn.addEventListener("click", function() {
-            OSMD.cursor.reset();
+            osmdObj.cursor.reset();
         });
         hideCursorBtn.addEventListener("click", function() {
-            OSMD.cursor.hide();
+            osmdObj.cursor.hide();
         });
         showCursorBtn.addEventListener("click", function() {
-            OSMD.cursor.show();
+            osmdObj.cursor.show();
         });
 
         backendSelect.addEventListener("change", function(e) {
             var value = e.target.value;
             // clears the canvas element
             canvas.innerHTML = "";
-            OSMD = new opensheetmusicdisplay.OSMD(canvas, false, value);
-            OSMD.setLogLevel('info');
+            osmdObj = new opensheetmusicdisplay.OSMD(canvas, false, value);
+            osmdObj.setLogLevel('info');
             selectOnChange();
 
         });
@@ -174,9 +176,9 @@
             str = folder + select.value;
         }
         zoom = 1.0;
-        OSMD.load(str).then(
+        osmdObj.load(str).then(
             function() {
-                return OSMD.render();
+                return osmdObj.render();
             },
             function(e) {
                 error("Error reading sheet: " + e);
@@ -208,8 +210,8 @@
     function scale() {
         disable();
         window.setTimeout(function(){
-            OSMD.zoom = zoom;
-            OSMD.render();
+            osmdObj.zoom = zoom;
+            osmdObj.render();
             enable();
         }, 0);
     }

+ 5 - 1
package.json

@@ -58,6 +58,9 @@
     "@types/chai": "^4.0.3",
     "@types/loglevel": "^1.4.29",
     "@types/mocha": "^2.2.40",
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-es2015": "^6.24.1",
     "browserify": "^14.0.0",
     "chai": "^4.1.0",
     "cz-conventional-changelog": "^2.0.0",
@@ -73,6 +76,7 @@
     "grunt-webpack": "^3.0.0",
     "grunt-webpack-server": "^0.1.0",
     "http-server": "^0.10.0",
+    "jquery": "^3.2.1",
     "jshint": "^2.9.4",
     "karma": "^1.1.1",
     "karma-base64-to-js-preprocessor": "^0.0.1",
@@ -93,7 +97,7 @@
     "typescript": "^2.6.1",
     "uglifyjs-webpack-plugin": "^1.0.1",
     "webpack": "^3.5.5",
-    "webpack-dev-server": "^2.9.1"
+    "webpack-dev-server": "2.7.1"
   },
   "config": {
     "commitizen": {

+ 2 - 2
src/MusicalScore/Graphical/MusicSheetDrawer.ts

@@ -239,7 +239,7 @@ export abstract class MusicSheetDrawer {
         // empty
     }
 
-    protected drawInstrumentBracket(bracket: GraphicalObject, system: MusicSystem): void {
+    protected drawInstrumentBrace(brace: GraphicalObject, system: MusicSystem): void {
         // empty
     }
 
@@ -300,7 +300,7 @@ export abstract class MusicSheetDrawer {
             }
         }
         for (let bracket of musicSystem.InstrumentBrackets) {
-            this.drawInstrumentBracket(bracket, musicSystem);
+            this.drawInstrumentBrace(bracket, musicSystem);
         }
         for (let bracket of musicSystem.GroupBrackets) {
             this.drawGroupBracket(bracket, musicSystem);

+ 42 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBracket.ts

@@ -0,0 +1,42 @@
+import Vex = require("vexflow");
+import {GraphicalObject} from "../GraphicalObject";
+import {VexFlowStaffLine} from "./VexFlowStaffLine";
+import { BoundingBox } from "../BoundingBox";
+import { VexFlowMeasure } from "./VexFlowMeasure";
+
+/**
+ * Class that defines a instrument bracket at the beginning of a line.
+ */
+export class VexFlowInstrumentBracket extends GraphicalObject {
+
+    private vexflowConnector: Vex.Flow.StaveConnector;
+
+    constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine) {
+        super();
+        // FIXME: B.Giesinger: Fill in sizes after calculation
+        this.boundingBox = new BoundingBox(this);
+        const firstVexMeasure: VexFlowMeasure = firstVexFlowStaffLine.Measures[0] as VexFlowMeasure;
+        const lastVexMeasure: VexFlowMeasure = lastVexFlowStaffLine.Measures[0] as VexFlowMeasure;
+        this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), Vex.Flow.StaveConnector.type.BRACE);
+    }
+
+    /**
+     * Render the bracket using the given backend
+     * @param ctx Render Vexflow context
+     */
+    public draw(ctx: Vex.Flow.RenderContext): void {
+        this.vexflowConnector.setContext(ctx).draw();
+    }
+
+    /**
+     * Adds a connector between two staves
+     *
+     * @param {Stave} stave1: First stave
+     * @param {Stave} stave2: Second stave
+     * @param {Flow.StaveConnector.type} type: Type of connector
+     */
+    private addConnector(stave1: Vex.Flow.Stave, stave2: Vex.Flow.Stave, type: any): void {
+        this.vexflowConnector = new Vex.Flow.StaveConnector(stave1, stave2)
+        .setType(type);
+    }
+}

+ 5 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -9,6 +9,7 @@ import {GraphicalObject} from "../GraphicalObject";
 import {GraphicalLayers} from "../DrawingEnums";
 import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
 import {VexFlowBackend} from "./VexFlowBackend";
+import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
 
 /**
  * This is a global constant which denotes the height in pixels of the space between two lines of the stave
@@ -83,8 +84,10 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
         }
     }
 
-    protected drawInstrumentBrace(bracket: GraphicalObject, system: MusicSystem): void {
-        // empty
+    protected drawInstrumentBrace(brace: GraphicalObject, system: MusicSystem): void {
+        // Draw InstrumentBrackets at beginning of line
+        const vexBrace: VexFlowInstrumentBracket = (brace as VexFlowInstrumentBracket);
+        vexBrace.draw(this.backend.getContext());
     }
 
     protected drawGroupBracket(bracket: GraphicalObject, system: MusicSystem): void {

+ 8 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSystem.ts

@@ -4,10 +4,12 @@ import {SystemLinesEnum} from "../SystemLinesEnum";
 import {SystemLinePosition} from "../SystemLinePosition";
 import {StaffMeasure} from "../StaffMeasure";
 import {SystemLine} from "../SystemLine";
+import {VexFlowStaffLine} from "./VexFlowStaffLine";
 import {VexFlowMeasure} from "./VexFlowMeasure";
 import {VexFlowConverter} from "./VexFlowConverter";
 import {StaffLine} from "../StaffLine";
 import {EngravingRules} from "../EngravingRules";
+import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
 
 export class VexFlowMusicSystem extends MusicSystem {
     constructor(parent: GraphicalMusicPage, id: number) {
@@ -50,7 +52,12 @@ export class VexFlowMusicSystem extends MusicSystem {
      * @param firstStaffLine the upper StaffLine (use a cast to get the VexFlowStaffLine) of the brace to create
      * @param lastStaffLine the lower StaffLine (use a cast to get the VexFlowStaffLine) of the brace to create
      */
-    protected createInstrumentBrace(firstStaffLine: StaffLine, lastStaffLine: StaffLine): void {
+    protected createInstrumentBracket(firstStaffLine: StaffLine, lastStaffLine: StaffLine): void {
+        // You could write this in one line but the linter doesn't let me.
+        const firstVexStaff: VexFlowStaffLine = (firstStaffLine as VexFlowStaffLine);
+        const lastVexStaff: VexFlowStaffLine = (lastStaffLine as VexFlowStaffLine);
+        const vexFlowBracket: VexFlowInstrumentBracket = new VexFlowInstrumentBracket(firstVexStaff, lastVexStaff);
+        this.InstrumentBrackets.push(vexFlowBracket);
         return;
     }
 

+ 23 - 16
webpack.config.js

@@ -2,14 +2,9 @@ var path = require('path');
 var webpack = require('webpack');
 
 module.exports = {
-  // entry: [
-  //   './src/OSMD/OSMD.ts'
-  //   // TODO: Add demo.js where the webdev server is implemented
-  //   //
-  // ],
   entry: {
-    'osmd': './src/OSMD/OSMD.ts',
-    'demo': './demo/demo.js'
+    'osmd': './src/OSMD/OSMD.ts', // Main library
+    'demo': './demo/index.js' // Demo index
   },
   output: {
       path: path.resolve(__dirname, 'build'),
@@ -22,26 +17,38 @@ module.exports = {
    module: {
        loaders: [
            // all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
-           { test: /\.tsx?$/, loader: 'ts-loader' }
+           { test: /\.tsx?$/, loader: 'ts-loader' },
+           // all files with a '.js' extension. Mostly for the web demo.
+           { test: /\.jsx?$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/,
+              query: {
+                presets: ['es2015'] 
+              }
+          },
        ]
    },
    plugins: [
      // build optimization plugins
      new webpack.LoaderOptionsPlugin({
       minimize: true,
-      debug: false
+      debug: true
     }),
-    new webpack.optimize.UglifyJsPlugin({
-        warnings: false,
-        beautify: false,
-        compress: true,
-        comments: false,
-        sourceMap: true
-      })
+    new webpack.ProvidePlugin({
+      $: 'jquery',
+      jQuery: 'jquery'
+    }),
+    // FIXME: use environment variable to control uglify.
+    // new webpack.optimize.UglifyJsPlugin({
+    //     warnings: false,
+    //     beautify: false,
+    //     compress: true,
+    //     comments: false,
+    //     sourceMap: true
+    //   })
   ],
   devServer: {
     contentBase: [
       path.join(__dirname, 'test/data'),
+      path.join(__dirname, 'build'),
       path.join(__dirname, 'demo')
       // TODO: fill in paths for demo data
     ],