OSMD.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. "use strict";
  2. var Xml_1 = require("./../Common/FileIO/Xml");
  3. var VexFlowMusicSheetCalculator_1 = require("./../MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator");
  4. var MusicSheetReader_1 = require("./../MusicalScore/ScoreIO/MusicSheetReader");
  5. var GraphicalMusicSheet_1 = require("./../MusicalScore/Graphical/GraphicalMusicSheet");
  6. var VexFlowMusicSheetDrawer_1 = require("./../MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer");
  7. var Cursor_1 = require("./Cursor");
  8. var Mxl_1 = require("../Common/FileIO/Mxl");
  9. //import {Promise} from "es6-promise";
  10. var ResizeHandler_1 = require("./ResizeHandler");
  11. var OSMD = (function () {
  12. /**
  13. * The easy way of displaying a MusicXML sheet music file
  14. * @param container is either the ID, or the actual "div" element which will host the music sheet
  15. * @autoResize automatically resize the sheet to full page width on window resize
  16. */
  17. function OSMD(container, autoResize) {
  18. if (autoResize === void 0) { autoResize = false; }
  19. this.zoom = 1.0;
  20. // Store container element
  21. if (typeof container === "string") {
  22. // ID passed
  23. this.container = document.getElementById(container);
  24. }
  25. else if (container && "appendChild" in container) {
  26. // Element passed
  27. this.container = container;
  28. }
  29. if (!this.container) {
  30. throw new Error("Please pass a valid div container to OSMD");
  31. }
  32. // Create the elements inside the container
  33. this.heading = document.createElement("div");
  34. this.canvas = document.createElement("canvas");
  35. this.canvas.style.zIndex = "0";
  36. var inner = document.createElement("div");
  37. inner.style.position = "relative";
  38. this.container.appendChild(this.heading);
  39. inner.appendChild(this.canvas);
  40. this.container.appendChild(inner);
  41. // Create the drawer
  42. this.drawer = new VexFlowMusicSheetDrawer_1.VexFlowMusicSheetDrawer(this.heading, this.canvas);
  43. // Create the cursor
  44. this.cursor = new Cursor_1.Cursor(inner, this);
  45. if (autoResize) {
  46. this.autoResize();
  47. }
  48. }
  49. /**
  50. * Load a MusicXML file
  51. * @param content is either the url of a file, or the root node of a MusicXML document, or the string content of a .xml/.mxl file
  52. */
  53. OSMD.prototype.load = function (content) {
  54. // Warning! This function is asynchronous! No error handling is done here.
  55. // FIXME TODO Refactor with Promises
  56. this.reset();
  57. var path = "Unknown path";
  58. if (typeof content === "string") {
  59. var str = content;
  60. if (str.substr(0, 4) === "http") {
  61. // Retrieve the file at the url
  62. path = str;
  63. this.openURL(path);
  64. return;
  65. }
  66. if (str.substr(0, 4) === "\x04\x03\x4b\x50") {
  67. // This is a zip file, unpack it first
  68. Mxl_1.openMxl(str).then(this.load, function (err) {
  69. throw new Error("OSMD: Invalid MXL file");
  70. });
  71. return;
  72. }
  73. if (str.substr(0, 5) === "<?xml") {
  74. // Parse the string representing an xml file
  75. var parser = new DOMParser();
  76. content = parser.parseFromString(str, "text/xml");
  77. }
  78. }
  79. if (!content || !content.nodeName) {
  80. throw new Error("OSMD: Document provided is not valid");
  81. }
  82. var elem = content.getElementsByTagName("score-partwise")[0];
  83. if (elem === undefined) {
  84. throw new Error("OSMD: Document is not valid partwise MusicXML");
  85. }
  86. var score = new Xml_1.IXmlElement(elem);
  87. var calc = new VexFlowMusicSheetCalculator_1.VexFlowMusicSheetCalculator();
  88. var reader = new MusicSheetReader_1.MusicSheetReader();
  89. this.sheet = reader.createMusicSheet(score, path);
  90. this.graphic = new GraphicalMusicSheet_1.GraphicalMusicSheet(this.sheet, calc);
  91. this.cursor.init(this.sheet.MusicPartManager, this.graphic);
  92. return; // Promise.resolve();
  93. };
  94. /**
  95. * Render the music sheet in the container
  96. */
  97. OSMD.prototype.render = function () {
  98. this.resetHeadings();
  99. if (!this.graphic) {
  100. throw new Error("OSMD: Before rendering a music sheet, please load a MusicXML file");
  101. }
  102. var width = this.container.offsetWidth;
  103. if (isNaN(width)) {
  104. throw new Error("OSMD: Before rendering a music sheet, please give the container a width");
  105. }
  106. // Set page width
  107. this.sheet.pageWidth = width / this.zoom / 10.0;
  108. // Calculate again
  109. this.graphic.reCalculate();
  110. // Update Sheet Page
  111. var height = this.graphic.MusicPages[0].PositionAndShape.BorderBottom * 10.0 * this.zoom;
  112. this.drawer.resize(width, height);
  113. this.drawer.scale(this.zoom);
  114. // Finally, draw
  115. this.drawer.drawSheet(this.graphic);
  116. // Update the cursor position
  117. this.cursor.update();
  118. };
  119. /**
  120. *
  121. * @param url
  122. */
  123. OSMD.prototype.openURL = function (url) {
  124. throw new Error("OSMD: Not implemented: Load sheet from URL");
  125. //let JSZipUtils: any;
  126. //let self: OSMD = this;
  127. //JSZipUtils.getBinaryContent(url, function (err, data) {
  128. // if(err) {
  129. // throw err;
  130. // }
  131. // return self.load(data);
  132. //});
  133. };
  134. /**
  135. * Clear all the titles from the headings element
  136. */
  137. OSMD.prototype.resetHeadings = function () {
  138. while (this.heading.firstChild) {
  139. this.heading.removeChild(this.heading.firstChild);
  140. }
  141. };
  142. /**
  143. * Initialize this object to default values
  144. * FIXME: Probably unnecessary
  145. */
  146. OSMD.prototype.reset = function () {
  147. this.sheet = undefined;
  148. this.graphic = undefined;
  149. this.zoom = 1.0;
  150. this.resetHeadings();
  151. };
  152. /**
  153. * Attach the appropriate handler to the window.onResize event
  154. */
  155. OSMD.prototype.autoResize = function () {
  156. var self = this;
  157. ResizeHandler_1.handleResize(function () {
  158. // empty
  159. }, function () {
  160. var width = Math.max(document.documentElement.clientWidth, document.body.scrollWidth, document.documentElement.scrollWidth, document.body.offsetWidth, document.documentElement.offsetWidth);
  161. self.container.style.width = width + "px";
  162. self.render();
  163. });
  164. };
  165. return OSMD;
  166. }());
  167. exports.OSMD = OSMD;