From 0187a5f952514042ea29d8ce332bce351f12e631 Mon Sep 17 00:00:00 2001 From: William Toohey Date: Tue, 29 Sep 2015 13:26:44 +1000 Subject: [PATCH] Add synced animations. --- js/HuesCanvas.js | 43 ++++++++++++++++++++++++++++++++++++------- js/ResourcePack.js | 8 ++++++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/js/HuesCanvas.js b/js/HuesCanvas.js index 39609ad..c7ffc9f 100644 --- a/js/HuesCanvas.js +++ b/js/HuesCanvas.js @@ -34,6 +34,7 @@ function HuesCanvas(element, aContext, core) { this.animTimeout = null; this.animFrame = null; + this.animSync = false; // for synced anims // set later this.blurDecay = null; @@ -181,13 +182,22 @@ HuesCanvas.prototype.animationLoop = function() { if(this.blackoutTimeout && this.aContext.currentTime > this.blackoutTimeout) { this.clearBlackout(); } - if(this.image && this.image.animated - && this.animTimeout < this.aContext.currentTime) { - this.animFrame++; - this.animFrame %= this.image.frameDurations.length; - this.animTimeout = this.aContext.currentTime + - this.image.frameDurations[this.animFrame]/1000; - this.needsRedraw = true; + if(this.image && this.image.animated){ + if(this.image.beatsPerAnim && this.core.currentSong && this.core.currentSong.charsPerBeat) { + var a = this.animFrame; + this.syncAnim(); + if(this.animFrame != a) { + this.needsRedraw = true; + // If you change to a non-synced song, this needs to be reset + this.animTimeout = this.aContext.currentTime; + } + } else if(this.animTimeout < this.aContext.currentTime) { + this.animFrame++; + this.animFrame %= this.image.frameDurations.length; + // Don't rebase to current time otherwise we may lag + this.animTimeout += this.image.frameDurations[this.animFrame]/1000; + this.needsRedraw = true; + } } if(this.blurStart) { var delta = this.aContext.currentTime - this.blurStart; @@ -224,9 +234,28 @@ HuesCanvas.prototype.setImage = function(image) { return; } if(image.animated) { + this.animBeat = null; this.animFrame = 0; this.animTimeout = this.aContext.currentTime + image.frameDurations[0]/1000; + if(image.beatsPerAnim && this.core.currentSong && this.core.currentSong.charsPerBeat) { + this.syncAnim(); + } + } +} + +HuesCanvas.prototype.syncAnim = function() { + var song = this.core.currentSong; + if(!song) { // fallback to default + return; + } + // This loops A-OK because the core's beatIndex never rolls over for a new loop + var beatLoc = (this.core.beatIndex / song.charsPerBeat) % this.image.beatsPerAnim; + this.animFrame = Math.floor(this.image.bitmaps.length * (beatLoc / this.image.beatsPerAnim)); + // for build + if(this.animFrame < 0) { + this.animFrame += this.image.bitmaps.length; } + this.animSync = true; } HuesCanvas.prototype.setColour = function(colour, isFade) { diff --git a/js/ResourcePack.js b/js/ResourcePack.js index 2593f64..f1921ac 100644 --- a/js/ResourcePack.js +++ b/js/ResourcePack.js @@ -286,6 +286,7 @@ Respack.prototype.parseSongFile = function(text) { song.buildupRhythm = el.getTag("buildupRhythm"); song.source = el.getTag("source"); + song.charsPerBeat = parseFloat(el.getTag("charsPerBeat")); // Because PackShit breaks everything if(this.name == "PackShit") { @@ -348,6 +349,7 @@ Respack.prototype.parseImageFile = function(text) { image.source = el.getTag("source"); // self reference defaults to avoid changing strings twice in future image.align = el.getTag("align", image.align); + image.beatsPerAnim = parseFloat(el.getTag("beatsPerAnim")); var frameDur = el.getTag("frameDuration"); if(frameDur) { image.frameDurations = [] @@ -425,7 +427,8 @@ Respack.prototype.parseSongQueue = function() { //"crc":this.quickCRC(file), TODO "sound":null, "enabled":true, - "filename":songFile.name}; + "filename":songFile.name, + "charsPerBeat": null}; songFile.getBlob("audio/mpeg3", function(sound) { // Because blobs are crap var fr = new FileReader(); @@ -456,7 +459,8 @@ Respack.prototype.parseImageQueue = function() { "frameDurations":[33], "source":null, "enabled":true, - "animated":true}; + "animated":true, + "beatsPerAnim": null}; this.images.push(anim); } this.imageLoadStart(imgFile, anim);