From 97913381960047220edfc745a7e3666f126ea7be Mon Sep 17 00:00:00 2001 From: William Toohey Date: Wed, 23 Sep 2015 00:28:24 +1000 Subject: [PATCH] HuesSettings implemented, minor code cleanups --- css/hues-w.css | 1 + js/HuesCanvas.js | 50 +++-- js/HuesCore.js | 108 ++++------ js/HuesSettings.js | 487 +++++++++++---------------------------------- js/HuesUI.js | 8 + js/ResourcePack.js | 1 - js/SoundManager.js | 13 +- js/hues-modern.js | 42 ---- 8 files changed, 198 insertions(+), 512 deletions(-) delete mode 100644 js/hues-modern.js diff --git a/css/hues-w.css b/css/hues-w.css index b7f8517..0d1f66e 100644 --- a/css/hues-w.css +++ b/css/hues-w.css @@ -11,6 +11,7 @@ top: 5px; overflow: hidden; border-radius: 0 10px 10px 0; + white-space: nowrap; } .hues-w-beatleft { transform: scaleX(-1); diff --git a/js/HuesCanvas.js b/js/HuesCanvas.js index e212429..c0eeb7f 100644 --- a/js/HuesCanvas.js +++ b/js/HuesCanvas.js @@ -9,6 +9,7 @@ function HuesCanvas(element, aContext, core) { this.needsRedraw = false; this.colour = 0xFFFFFF; this.image = null; + this.smartAlign = true; // avoid string comparisons every frame this.animTimeout; this.animFrame; @@ -39,9 +40,9 @@ function HuesCanvas(element, aContext, core) { this.blendMode = "hard-light"; // Chosen because they look decent - this.setBlurAmount(15); - this.setBlurIterations(5); - this.setBlurDecay(25); + this.setBlurAmount("medium"); + this.setBlurQuality("high"); + this.setBlurDecay("fast"); this.canvas = document.getElementById(element).getContext("2d"); window.addEventListener('resize', this.resizeHandler(this)); this.resize(); @@ -87,16 +88,20 @@ HuesCanvas.prototype.redraw = function() { if(this.image) { var bitmap = this.image.animated ? this.image.bitmaps[this.animFrame] : this.image.bitmap; - switch(this.image.align) { - case "left": - offset = 0; - break; - case "right": - offset = width - bitmap.width; - break; - default: - offset = width/2 - bitmap.width/2; - break; + if(this.smartAlign) { + switch(this.image.align) { + case "left": + offset = 0; + break; + case "right": + offset = width - bitmap.width; + break; + default: + offset = width/2 - bitmap.width/2; + break; + } + } else { + offset = width/2 - bitmap.width/2; } if(this.xBlur || this.yBlur) { this.canvas.globalAlpha = this.blurAlpha; @@ -218,6 +223,9 @@ HuesCanvas.prototype.doBlackout = function(whiteout) { this.blackoutStart = this.aContext.currentTime; this.blackout = true; this.needsRedraw = true; + if(localStorage["blackoutUI"] == "on") { + core.userInterface.hide(); + } } // for song changes @@ -225,6 +233,9 @@ HuesCanvas.prototype.clearBlackout = function() { this.blackout = false; this.blackoutTimeout = 0; this.needsRedraw = true; + if(localStorage["blackoutUI"] == "on") { + core.userInterface.show(); + } } HuesCanvas.prototype.doShortBlackout = function(beatTime) { @@ -280,19 +291,24 @@ HuesCanvas.prototype.doYBlur = function() { } HuesCanvas.prototype.setBlurDecay = function(decay) { - this.blurDecay = decay; + this.blurDecay = {"slow" : 10, "medium" : 15, "fast" : 22, "faster!" : 30}[decay]; } -HuesCanvas.prototype.setBlurIterations = function(iterations) { - this.blurIterations = iterations; +HuesCanvas.prototype.setBlurQuality = function(quality) { + this.blurIterations = {"low" : 3, "medium" : 11, "high" : 19, "extreme" : 35}[quality]; this.blurDelta = this.blurAmount / this.blurIterations; this.blurAlpha = 1/(this.blurIterations/2); } HuesCanvas.prototype.setBlurAmount = function(amount) { - this.blurAmount = amount; + this.blurAmount = {"low" : 9, "medium" : 15, "high" : 25}[amount]; this.blurMin = -this.blurAmount/2; this.blurMax = this.blurAmount/2; + this.blurDelta = this.blurAmount / this.blurIterations; +} + +HuesCanvas.prototype.setSmartAlign = function(align) { + this.smartAlign = align == "on"; } HuesCanvas.prototype.setAnimating = function(anim) { diff --git a/js/HuesCore.js b/js/HuesCore.js index d340dcc..cbef55c 100644 --- a/js/HuesCore.js +++ b/js/HuesCore.js @@ -1,19 +1,3 @@ -var defaultSettings = { - load : true, // Debugging var, for loading zips or not - autoplay : true, // Debug, play first song automatically? - blurQuality: 2, // low/med/high/extreme 0-3 - - // UI accessible config - // Autosong stuff is a todo, becuase why even implement that - smartAlign: true, - blurAmount: 1, // 0,1,2,3 = off,low,med,high - blurDecay: 2, // 0,1,2,3 = slow,med,fast,faster! - colourSet: "normal", // normal, pastel, 420 - blackoutUI: false, - playBuildups: "on", // off, once, on - volume : 0.7 -} - HuesCore = function(defaults) { // Bunch-o-initialisers this.version = "0x01"; @@ -25,31 +9,20 @@ HuesCore = function(defaults) { this.colourIndex=0; this.imageIndex=-1; this.isFullAuto = true; - this.currentVolume=70; - this.volumeMuted=false; this.loopCount=0; - this.doRandom = false; - this.lastSC=0; - this.buildupDiff=0; - this.animTimeoutID; this.fadeOut=false; this.fadeDirection=false; this.loadedFiles=0; this.doBuildup=true; this.userInterface = null; - for(var attr in defaultSettings) { - if(defaults[attr] == undefined) - defaults[attr] = defaultSettings[attr]; - } - console.log("0x40 Hues - start your engines!"); this.colours = this.oldColours; this.uiArray = []; this.lastSongArray = []; this.lastImageArray = []; this.settings = new HuesSettings(defaults); - this.autoSong = this.settings.autosong; + //this.autoSong = this.settings.autosong; this.resourceManager = new Resources(); this.soundManager = new SoundManager(); if(!this.soundManager.canUse) { @@ -62,7 +35,6 @@ HuesCore = function(defaults) { this.changeUI(1); this.settings.connectCore(this); - // todo: only after respacks loaded? var that = this; if(defaults.load) { this.resourceManager.addAll(defaults.respacks, function() { @@ -113,6 +85,9 @@ HuesCore.prototype.animationLoop = function() { this.userInterface.updateTime(0); } else { this.userInterface.updateTime(this.soundManager.displayableTime()); + if(this.doBuildup) { + this.currentSong.buildupPlayed = true; + } } for(var beatTime = this.beatIndex * this.beatLength; beatTime < now; beatTime = ++this.beatIndex * this.beatLength) { @@ -164,34 +139,23 @@ HuesCore.prototype.setSong = function(index) { this.userInterface.setSongText(); this.loopCount = 0; if (this.currentSong.buildup) { - if (this.currentSong.force) { - if (this.currentSong.force != "song") { - this.currentSong.buildupPlayed = false; - this.doBuildup = true; - } else { - this.currentSong.buildupPlayed = true; - this.doBuildup = false; - } - this.currentSong.force = null; - } else { - switch (this.settings.buildups) { - case "off": - this.currentSong.buildupPlayed = true; - this.doBuildup = false; - break; - case "on": - this.currentSong.buildupPlayed = false; - this.doBuildup = true; - break; - case "once": - this.doBuildup = !this.currentSong.buildupPlayed; - break; - } + switch (localStorage["playBuildups"]) { + case "off": + this.currentSong.buildupPlayed = true; + this.doBuildup = false; + break; + case "on": + this.currentSong.buildupPlayed = false; + this.doBuildup = true; + break; + case "once": + this.doBuildup = !this.currentSong.buildupPlayed; + break; } } this.resetAudio(); var that = this; - this.soundManager.playSong(this.currentSong, function() { + this.soundManager.playSong(this.currentSong, this.doBuildup, function() { that.fillBuildup(); }); } @@ -266,8 +230,6 @@ HuesCore.prototype.resetAudio = function() { this.samplePosition = 0; this.beatIndex = 0; this.position = 0; - this.lastSC = 0; - this.buildupDiff = 0; this.songDataUpdated(); } @@ -494,23 +456,11 @@ HuesCore.prototype.changeUI = function(index) { } HuesCore.prototype.settingsUpdated = function() { - console.log("Updating according to this.settings"); - this.blurMultiplier = {"low":0.5, "medium":1, "high":4}[this.settings.blurAmount]; - this.blurDecayMultiplier = {"low":0.3, "medium":0.6, "high":1, "vhigh":1.6}[this.settings.blurDecay]; - //this.settings.blackoutUI; - // todo: blackoutUI - switch (this.settings.colours) { - case "normal": - this.colours = this.oldColours; - break; - case "pastel": - this.colours = this.pastelColours; - break; - case "gp": - this.colours = this.weedColours; - break; - } - switch (this.settings.ui) { + this.renderer.setSmartAlign(localStorage["smartAlign"]); + this.renderer.setBlurAmount(localStorage["blurAmount"]); + this.renderer.setBlurDecay(localStorage["blurDecay"]); + this.renderer.setBlurQuality(localStorage["blurQuality"]); + switch (localStorage["currentUI"]) { case "retro": this.changeUI(0); break; @@ -524,6 +474,20 @@ HuesCore.prototype.settingsUpdated = function() { this.changeUI(3); break; } + switch (localStorage["colourSet"]) { + case "normal": + this.colours = this.oldColours; + break; + case "pastel": + this.colours = this.pastelColours; + break; + case "gp": + this.colours = this.weedColours; + break; + } + if(localStorage["blackoutUI"] == "on") { + this.userInterface.show(); + } /*if (this.autoSong == "off" && !(this.settings.autosong == "off")) { console.log("Resetting loopCount since AutoSong was enabled"); this.loopCount = 0; diff --git a/js/HuesSettings.js b/js/HuesSettings.js index 61226ca..a1b2826 100644 --- a/js/HuesSettings.js +++ b/js/HuesSettings.js @@ -1,388 +1,123 @@ -function HuesSettings(defaults) { - this.core = null; - // TODO: HTML5 local storage or something -} - -HuesSettings.prototype.connectCore = function(core) { - this.core = core; -}; -/* -//class HuesSettings -package -{ - import flash.display.*; - import flash.net.*; +HuesSettings.prototype.defaultSettings = { + // Debugging var, for loading zips or not + load : true, + // Debug, play first song automatically? + autoplay : true, + // If true, defaults passed in initialiser override locally saved + overwriteLocal : false, - public class HuesSettings extends Object - { - public function HuesSettings() - { - this.bools = ["imageSmoothing", "blurEnabled", "smartAlign", "autosongShuffle", "blackoutUI"]; - this.numbs = ["autosongDelay"]; - super(); - trace("Settings created"); - this.callbacks = []; - this.currentSettings = {}; - this.setDefaults(); - this.load(); - return; - } - - public function set autosongDelay(arg1:int):void - { - trace("AutoSong delay:", arg1); - this.currentSettings["autosongDelay"] = arg1; - this.callCallbacks(); - return; - } - - public function set autosongShuffle(arg1:Boolean):void - { - trace("Image scaling:", arg1); - this.currentSettings["autosongShuffle"] = arg1; - this.callCallbacks(); - return; - } - - public function set imagescaling(arg1:String):void - { - trace("Image scaling:", arg1); - this.currentSettings["imagescaling"] = arg1; - this.callCallbacks(); - return; - } - - public function set colors(arg1:String):void - { - trace("Colors:", arg1); - this.currentSettings["colors"] = arg1; - this.callCallbacks(); - return; - } - - internal function setDefaults():void - { - this.currentSettings = {"flashQuality":flash.display.StageQuality.HIGH, "imageSmoothing":true, "blurEnabled":true, "blurAmount":"medium", "blurDecay":"high", "channels":"stereo", "smartAlign":true, "buildups":"once", "blendMode":"hard", "ui":"modern", "autosong":"off", "autosongDelay":5, "autosongShuffle":true, "imagescaling":"on", "colors":"normal", "blackoutUI":false}; - return; - } - - public function defaults():void - { - this.setDefaults(); - this.saveSettings(); - return; - } - - public function getSettingsFromParameters(arg1:Object):void - { - var loc1:*=undefined; - var loc2:*=null; - if (arg1) - { - var loc3:*=0; - var loc4:*=arg1; - for (loc2 in loc4) - { - loc1 = arg1[loc2]; - if (this.bools.indexOf(loc2) == -1) - { - if (this.numbs.indexOf(loc2) != -1) - { - if (loc1.match(new RegExp("\\d+"))) - { - loc1 = int(loc1); - if (loc2 == "autosongDelay") - { - loc1 = Math.max(1, loc1); - } - } - else - { - loc1 = null; - } - } - } - else if (loc1 != "true") - { - if (loc1 != "false") - { - loc1 = null; - } - else - { - loc1 = false; - } - } - else - { - loc1 = true; - } - if (loc1 == null) - { - continue; - } - this.currentSettings[loc2] = loc1; - } - this.saveSettings(); - this.callCallbacks(); - } - return; - } - - public function saveSettings():void - { - var so:flash.net.SharedObject; - var k:String; - - var loc1:*; - k = null; - trace("Saving settings!"); - so = flash.net.SharedObject.getLocal(this.objectName); - var loc2:*=0; - var loc3:*=this.currentSettings; - for (k in loc3) - { - so.data[k] = this.currentSettings[k]; - } - so.data.saved = true; - try - { - so.flush(); - } - catch (e:Error) - { - trace("Saving settings failed, oh well"); - } - return; - } - - public function load():void - { - var loc1:*=flash.net.SharedObject.getLocal(this.objectName); - if ("saved" in loc1.data) - { - trace("Old settings"); - this.currentSettings = loc1.data; - } - else - { - trace("Defaults"); - this.defaults(); - } - this.callCallbacks(); - return; - } - - public function set blackoutUI(arg1:Boolean):void - { - trace("Blackout UI:", arg1); - this.currentSettings["blackoutUI"] = arg1; - this.callCallbacks(); - return; - } - - public function addCallback(arg1:Function):void - { - if (this.callbacks.indexOf(arg1) == -1) - { - this.callbacks.push(arg1); - arg1(); - } - return; - } - - public function callCallbacks():void - { - var loc1:*=undefined; - this.saveSettings(); - var loc2:*=0; - var loc3:*=this.callbacks; - for each (loc1 in loc3) - { - loc1(); - } - return; - } - - public function get flashQuality():String - { - return this.currentSettings["flashQuality"]; - } - - public function get imageSmoothing():Boolean - { - return this.currentSettings["imageSmoothing"]; - } - - public function get blurEnabled():Boolean - { - return this.currentSettings["blurEnabled"]; - } - - public function get blurAmount():String - { - return this.currentSettings["blurAmount"]; - } - - public function get blurDecay():String - { - return this.currentSettings["blurDecay"]; - } - - public function get channels():String - { - return this.currentSettings["channels"]; - } - - public function get smartAlign():Boolean - { - return this.currentSettings["smartAlign"]; - } - - public function get buildups():String - { - return this.currentSettings["buildups"]; - } - - public function get blendMode():String - { - return this.currentSettings["blendMode"]; - } - - public function get ui():String - { - return this.currentSettings["ui"]; - } - - public function get autosong():String - { - return this.currentSettings["autosong"]; - } - - public function get autosongDelay():int - { - return this.currentSettings["autosongDelay"]; - } - - public function get autosongShuffle():Boolean - { - return this.currentSettings["autosongShuffle"]; - } - - public function get imagescaling():String - { - return this.currentSettings["imagescaling"]; - } - - public function get colors():String - { - return this.currentSettings["colors"]; - } - - public function get blackoutUI():Boolean - { - return this.currentSettings["blackoutUI"]; - } - - public function set flashQuality(arg1:String):void - { - trace("Flash quality:", arg1); - this.currentSettings["flashQuality"] = arg1; - this.callCallbacks(); - return; - } - - public function set imageSmoothing(arg1:Boolean):void - { - trace("Image smoothing:", arg1); - this.currentSettings["imageSmoothing"] = arg1; - this.callCallbacks(); - return; - } - - public function set blurEnabled(arg1:Boolean):void - { - trace("Blur:", arg1); - this.currentSettings["blurEnabled"] = arg1; - this.callCallbacks(); - return; - } - - public function set blurAmount(arg1:String):void - { - trace("Blur amount:", arg1); - this.currentSettings["blurAmount"] = arg1; - this.callCallbacks(); - return; - } - - public function set blurDecay(arg1:String):void - { - trace("Blur decay:", arg1); - this.currentSettings["blurDecay"] = arg1; - this.callCallbacks(); - return; - } - - public function set channels(arg1:String):void - { - trace("Channels:", arg1); - this.currentSettings["channels"] = arg1; - this.callCallbacks(); - return; - } + // UI accessible config + // Autosong stuff is a todo, becuase why even implement that + smartAlign: "on", + blurAmount: "medium", + blurDecay: "fast", + blurQuality: "high", + currentUI: "modern", + colourSet: "normal", + blackoutUI: "off", + playBuildups: "on", + volume : 0.7 +} - public function set smartAlign(arg1:Boolean):void - { - trace("Smart align:", arg1); - this.currentSettings["smartAlign"] = arg1; - this.callCallbacks(); - return; - } +// To dynamically build the UI like the cool guy I am +HuesSettings.prototype.settingsCategories = { + "Image Settings" : [ + "smartAlign", + "blurAmount", + "blurDecay", + "blurQuality" + ], + "UI Settings" : [ + "currentUI", + "colourSet", + "blackoutUI" + ], + "Audio Settings" : [ + "playBuildups" + ] +} - public function set buildups(arg1:String):void - { - trace("Buildups:", arg1); - this.currentSettings["buildups"] = arg1; - this.callCallbacks(); - return; - } +HuesSettings.prototype.settingsOptions = { + smartAlign : { + name : "Smart Align Images", + options : ["on", "off"] + }, + blurAmount : { + name : "Blur Amount", + options : ["low", "med", "high"] + }, + blurDecay : { + name : "Blur Decay", + options : ["slow", "medium", "fast", "faster!"] + }, + blurQuality : { + name : "Blur Quality", + options : ["low", "medium", "high", "extreme"] + }, + currentUI : { + name : "User Interface", + options : ["retro", "weed", "modern", "xmas"] + }, + colourSet : { + name : "Colour Set", + options : ["normal", "pastel", "420"] + }, + blackoutUI : { + name : "Blackout affects UI", + options : ["on", "off"] + }, + playBuildups : { + name : "Play buildups", + options : ["off", "once", "on"] + } + +} - public function set blendMode(arg1:String):void - { - trace("Blend mode:", arg1); - this.currentSettings["blendMode"] = arg1; - this.callCallbacks(); - return; +function HuesSettings(defaults) { + this.core = null; + + for(var attr in this.defaultSettings) { + if(attr == "respacks") { + continue; } - - public function set ui(arg1:String):void - { - trace("UI:", arg1); - this.currentSettings["ui"] = arg1; - this.callCallbacks(); - return; + if(defaults[attr] == undefined) { + defaults[attr] = this.defaultSettings[attr]; + } else if(defaults.overwriteLocal) { + localStorage[attr] = defaults[attr]; } - - public function set autosong(arg1:String):void - { - trace("AutoSong:", arg1); - this.currentSettings["autosong"] = arg1; - this.callCallbacks(); - return; + // populate defaults, ignoring current + if(localStorage[attr] == undefined) { + localStorage[attr] = defaults[attr]; } + } + + this.defaults = defaults; +} - internal var currentSettings:Object; - - internal var bools:Array; - - internal var numbs:Array; - - internal var objectName:*="HuesSettings51"; +HuesSettings.prototype.connectCore = function(core) { + this.core = core; + core.settingsUpdated(); +}; - internal var callbacks:Array; +// Set a named index to its named value, returns false if name doesn't exist +HuesSettings.prototype.set = function(setting, value) { + value = value.toLowerCase(); + var opt = this.settingsOptions[setting]; + if(!opt || opt.options.indexOf(value) == -1) { + return false; } + localStorage[setting] = value; + core.settingsUpdated(); + return true; } - -*/ \ No newline at end of file +// Note: This is not defaults as per defaultSettings, but those merged with +// the defaults given in the initialiser +HuesSettings.prototype.setDefaults = function() { + for(var attr in this.defaults) { + if(attr == "respacks") { + continue; + } + localStorage[attr] = this.defaults[attr]; + } +} \ No newline at end of file diff --git a/js/HuesUI.js b/js/HuesUI.js index fec4ef6..810f080 100644 --- a/js/HuesUI.js +++ b/js/HuesUI.js @@ -61,6 +61,14 @@ HuesUI.prototype.disconnect = function() { this.root.style.display = "none"; } +HuesUI.prototype.show = function() { + this.root.style.display = "block"; +} + +HuesUI.prototype.hide = function() { + this.root.style.display = "none"; +} + // May do nothing, may scale elements if needed etc etc HuesUI.prototype.resize = function() {} HuesUI.prototype.modeUpdated = function() {} diff --git a/js/ResourcePack.js b/js/ResourcePack.js index 3873c24..20a1674 100644 --- a/js/ResourcePack.js +++ b/js/ResourcePack.js @@ -77,7 +77,6 @@ Respack.prototype.loadFromURL = function(url, callback, progress) { // Unable to compute progress information since the total size is unknown } } - req.on req.send(); } diff --git a/js/SoundManager.js b/js/SoundManager.js index 1763457..d796e5c 100644 --- a/js/SoundManager.js +++ b/js/SoundManager.js @@ -55,7 +55,7 @@ function SoundManager() { }, false); } -SoundManager.prototype.playSong = function(song, callback) { +SoundManager.prototype.playSong = function(song, playBuild, callback) { var that = this; if(this.song == song) { return; @@ -66,7 +66,6 @@ SoundManager.prototype.playSong = function(song, callback) { this.loadBuffer(song, function() { // To prevent race condition if you press "next" twice fast if(song == that.song) { - that.startTime = that.context.currentTime + that.loopStart; that.bufSource = that.context.createBufferSource(); that.bufSource.buffer = that.buffer; that.bufSource.loop = true; @@ -74,8 +73,14 @@ SoundManager.prototype.playSong = function(song, callback) { that.bufSource.loopEnd = that.buffer.duration; that.bufSource.connect(that.gainNode); - // Mobile Safari requires offset, even if 0 - that.bufSource.start(0); + if(playBuild) { + // Mobile Safari requires offset, even if 0 + that.bufSource.start(0); + that.startTime = that.context.currentTime + that.loopStart; + } else { + that.bufSource.start(0, that.loopStart); + that.startTime = that.context.currentTime; + } // offset to after the build //that.startTime = that.context.currentTime + that.loopStart; that.playing = true; diff --git a/js/hues-modern.js b/js/hues-modern.js deleted file mode 100644 index 1c3355f..0000000 --- a/js/hues-modern.js +++ /dev/null @@ -1,42 +0,0 @@ -Self.prototype.updateVolume = function(muted, gain) { - var label = this.volLabel - var input = this.volInput - - var text = gain.toFixed(1) + "dB" - if (muted) { - text = "(" + text + ")" - } - label.textContent = text - input.value = gain -} - -Self.prototype.setupVolume = function(box) { - var volBar = box.ownerDocument.createElement("div") - volBar.className = "hues-m-vol-bar" - box.appendChild(volBar) - - var label = box.ownerDocument.createElement("button") - volBar.appendChild(label) - this.volLabel = label - label.addEventListener("click", (function() { - if (this.core.isMuted()) { - this.core.unmute() - } else { - this.core.mute() - } - }).bind(this)) - - var input = box.ownerDocument.createElement("input") - input.type = "range" - input.min = -60 - input.max = 5 - input.step = 1 - volBar.appendChild(input) - this.volInput = input - input.addEventListener("input", (function() { - this.core.setVolume(parseFloat(input.value)) - }).bind(this)) - - this.updateVolume(this.core.isMuted(), this.core.getVolume()) - Hues.addEventListener("volumechange", this.updateVolume.bind(this)) -} \ No newline at end of file