var supportsAudio = require('./supports-audio'); var registerAudioContext = require('./register-audio-context'); var activeAudioContext = require('./active-audio-context'); var loopImage = require('./images/loop.svg.js'); var playImage = require('./images/play.svg.js'); var pauseImage = require('./images/pause.svg.js'); var loadingImage = require('./images/loading.svg.js'); var resetImage = require('./images/reset.svg.js'); function CreateSynthControl(parent, options) { var self = this; // parent is either an element or a selector. if (typeof parent === "string") { var selector = parent; parent = document.querySelector(selector); if (!parent) throw new Error("Cannot find element \"" + selector + "\" in the DOM."); } else if (!(parent instanceof HTMLElement)) throw new Error("The first parameter must be a valid element or selector in the DOM."); self.parent = parent; self.options = {}; if (options) self.options = Object.assign({},options); // This can be called in the following cases: // AC already registered and not suspended // AC already registered and suspended // AC not registered and not passed in // AC not registered but passed in (but suspended) // AC not registered but passed in (not suspended) // If the AC is already registered, then just use it - ignore what is passed in // Create the AC if necessary if there isn't one already. // We don't care right now if the AC is suspended - whenever a button is clicked then we check it. if (self.options.ac) registerAudioContext(self.options.ac); buildDom(self.parent, self.options); attachListeners(self); self.disable = function(isDisabled) { var el = self.parent.querySelector(".abcjs-inline-audio"); if (isDisabled) el.classList.add("abcjs-disabled"); else el.classList.remove("abcjs-disabled"); }; self.setWarp = function(tempo, warp) { var el = self.parent.querySelector(".abcjs-midi-tempo"); el.value = Math.round(warp); self.setTempo(tempo) }; self.setTempo = function(tempo) { var el = self.parent.querySelector(".abcjs-midi-current-tempo"); if (el) el.innerHTML = Math.round(tempo); }; self.resetAll = function() { var pushedButtons = self.parent.querySelectorAll(".abcjs-pushed"); for (var i = 0; i < pushedButtons.length; i++) { var button = pushedButtons[i]; button.classList.remove("abcjs-pushed"); } }; self.pushPlay = function(push) { var startButton = self.parent.querySelector(".abcjs-midi-start"); if (!startButton) return; if (push) startButton.classList.add("abcjs-pushed"); else startButton.classList.remove("abcjs-pushed"); }; self.pushLoop = function(push) { var loopButton = self.parent.querySelector(".abcjs-midi-loop"); if (!loopButton) return; if (push) loopButton.classList.add("abcjs-pushed"); else loopButton.classList.remove("abcjs-pushed"); }; self.setProgress = function (percent, totalTime) { var progressBackground = self.parent.querySelector(".abcjs-midi-progress-background"); var progressThumb = self.parent.querySelector(".abcjs-midi-progress-indicator"); if (!progressBackground || !progressThumb) return; var width = progressBackground.clientWidth; var left = width * percent; progressThumb.style.left = left + "px"; var clock = self.parent.querySelector(".abcjs-midi-clock"); if (clock) { var totalSeconds = (totalTime * percent) / 1000; var minutes = Math.floor(totalSeconds / 60); var seconds = Math.floor(totalSeconds % 60); var secondsFormatted = seconds < 10 ? "0" + seconds : seconds; clock.innerHTML = minutes + ":" + secondsFormatted; } }; if (self.options.afterResume) { var isResumed = false; if (self.options.ac) { isResumed = self.options.ac.state !== "suspended"; } else if (activeAudioContext()) { isResumed = activeAudioContext().state !== "suspended"; } if (isResumed) self.options.afterResume(); } } function buildDom(parent, options) { var hasLoop = !!options.loopHandler; var hasRestart = !!options.restartHandler; var hasPlay = !!options.playHandler || !!options.playPromiseHandler; var hasProgress = !!options.progressHandler; var hasWarp = !!options.warpHandler; var hasClock = options.hasClock !== false; var html = '