From bdeacc3531860a6a1b4fabfa5218aa28662b222c Mon Sep 17 00:00:00 2001 From: William Toohey Date: Wed, 19 Oct 2016 01:56:56 +1000 Subject: [PATCH] Add 'Slice' effect. --- src/js/HuesCanvas.js | 92 ++++++++++++++++++++++++++++++++++++++++++++ src/js/HuesCore.js | 39 ++++++++++++------- src/js/HuesInfo.js | 4 +- 3 files changed, 121 insertions(+), 14 deletions(-) diff --git a/src/js/HuesCanvas.js b/src/js/HuesCanvas.js index 823f4b4..d013134 100644 --- a/src/js/HuesCanvas.js +++ b/src/js/HuesCanvas.js @@ -57,6 +57,13 @@ class HuesCanvas { this.xBlur = false; this.yBlur = false; + this.sliceAvgSegments = 15; + this.sliceCount = 0; + this.sliceSegments = []; + this.sliceDistances = []; + this.sliceDistance = 0; + this.sliceStart = 0; + // trippy mode this.trippyStart = [0, 0]; // x, y this.trippyRadii = [0, 0]; // x, y @@ -166,6 +173,13 @@ class HuesCanvas { } else { offset = width/2 - drawWidth/2; } + + if(this.sliceStart) { + bitmap = this.drawSlice(bitmap, drawWidth, drawHeight, width, height); + drawWidth = width; + drawHeight = height; + } + if(this.xBlur || this.yBlur) { this.drawBlur(bitmap, offset, drawWidth, drawHeight); }else { @@ -203,6 +217,27 @@ class HuesCanvas { } } + drawSlice(bitmap, drawWidth, drawHeight, width, height) { + this.offContext.clearRect(0,0,width,height); + + let bitmapoffset = 0; + let drawOffset = 0; + for(let i = 0; i < this.sliceCount; i++) { + let segment = this.sliceSegments[i]; + let segmentBitmapHeight = Math.round(segment * bitmap.height); + let segmentDrawHeight = Math.round(segment * drawHeight); + this.offContext.drawImage(bitmap, + 0 , bitmapoffset, // subsection x, y + bitmap.width, segmentBitmapHeight, // sub w/h + this.sliceDistances[i] * this.sliceDistance, drawOffset, // drawn section x, y + drawWidth, segmentDrawHeight); // drawn w/h + bitmapoffset += segmentBitmapHeight; + drawOffset += segmentDrawHeight; + } + + return this.offCanvas; + } + drawBlur(bitmap, offset, drawWidth, drawHeight) { this.context.globalAlpha = this.blurAlpha; if(this.xBlur) { @@ -310,6 +345,29 @@ class HuesCanvas { else this.core.blurUpdated(0, dist); } + if(this.sliceStart) { + let transitionPercent = 0.8; + let delta; + let now = this.audio.currentTime; + if(now < this.sliceRampUp) { + delta = this.sliceRampUp - now; + this.sliceDistance = (1-(delta / this.sliceTransitionTime)) * transitionPercent; + } else if(now < this.sliceRampDown) { + delta = this.sliceRampDown - now; + let longTransition = this.sliceRampDown - this.sliceRampUp; + this.sliceDistance = transitionPercent + ((1-(delta / longTransition)) * (1-transitionPercent)); + } else { + let endEffect = this.sliceRampDown + this.sliceTransitionTime; + if(now > endEffect) { + this.sliceStart = 0; + this.sliceDistance = 0; + } else { + delta = endEffect - now; + this.sliceDistance = delta / this.sliceTransitionTime; + } + } + this.needsRedraw = true; + } if(this.trippyStart[0] || this.trippyStart[1]) { for(let i = 0; i < 2; i++) { this.trippyRadii[i] = Math.floor((this.audio.currentTime - this.trippyStart[i]) * this.trippyRadius) * 2; @@ -497,6 +555,40 @@ class HuesCanvas { this.doYBlur(); this.trippyOn = saveTrippy; } + + doSlice(beatLength, beatCount) { + let transitionTime = Math.min(0.06, beatLength); + + this.sliceStart = this.audio.currentTime; + this.sliceRampUp = this.sliceStart + transitionTime; + this.sliceRampDown = this.sliceStart + (beatLength * beatCount) - transitionTime; + this.sliceTransitionTime = transitionTime; + + this.generateSliceSegments(); + this.needsRedraw = true; + } + + generateSliceSegments() { + let even = 1.0 / this.sliceAvgSegments; + let spread = even / 2; + let total = 0; + let i; + for(i = 0; ; i++) { + let deviation = Math.random() * spread*2 - spread; + let rando = even + deviation; + this.sliceSegments[i] = rando; + total += this.sliceSegments[i]; + + this.sliceDistances[i] = Math.random() * this.blurAmount - this.blurAmount/2; + + if(total > 1.0) { + this.sliceSegments[i] -= total - 1.0; + break; + } + } + this.sliceCount = i+1; + + } setBlurDecay(decay) { this.blurDecay = {"slow" : 7.8, "medium" : 14.1, "fast" : 20.8, "faster!" : 28.7}[decay]; diff --git a/src/js/HuesCore.js b/src/js/HuesCore.js index 40c6994..856fb1c 100644 --- a/src/js/HuesCore.js +++ b/src/js/HuesCore.js @@ -766,20 +766,13 @@ class HuesCore { } /* falls through */ case '~': - // case: fade in build, not in rhythm. Must max out fade timer. - let maxSearch = this.currentSong.rhythm.length; - if(this.beatIndex < 0) { - maxSearch -= this.beatIndex; - } - let fadeLen; - for (fadeLen = 1; fadeLen <= maxSearch; fadeLen++) { - if (this.getBeat(fadeLen + this.beatIndex) != ".") { - break; - } - } - this.renderer.doColourFade((fadeLen * this.getBeatLength()) / this.soundManager.playbackRate); + this.renderer.doColourFade(this.timeToNextBeat()); this.randomColour(true); break; + case 'S': + case 's': + this.renderer.doSlice(this.getBeatLength(), this.charsToNextBeat()); + break; case 'I': if (this.isFullAuto) { this.randomImage(); @@ -792,13 +785,33 @@ class HuesCore { if ([".", "+", "|", "¤"].indexOf(beat) == -1) { this.renderer.clearBlackout(); } - if([".", "+", "¤", ":", "*", "X", "O", "~", "=", "i", "I"].indexOf(beat) == -1) { + if([".", "+", "¤", ":", "*", "X", "O", "~", "=", "i", "I", "s"].indexOf(beat) == -1) { this.randomColour(); if (this.isFullAuto) { this.randomImage(); } } } + + + charsToNextBeat() { + // case: fade in build, not in rhythm. Must max out fade timer. + let maxSearch = this.currentSong.rhythm.length; + if(this.beatIndex < 0) { + maxSearch -= this.beatIndex; + } + let nextBeat; + for (nextBeat = 1; nextBeat <= maxSearch; nextBeat++) { + if (this.getBeat(nextBeat + this.beatIndex) != ".") { + break; + } + } + return nextBeat; + } + + timeToNextBeat() { + return (this.charsToNextBeat() * this.getBeatLength()) / this.soundManager.playbackRate; + } getBeatString(length) { length = length ? length : 256; diff --git a/src/js/HuesInfo.js b/src/js/HuesInfo.js index 722ac69..1b54636 100644 --- a/src/js/HuesInfo.js +++ b/src/js/HuesInfo.js @@ -41,7 +41,9 @@ const beatGlossary = [ "~ Fade color", "= Fade and change image", "i Invert all colours", - "I Invert & change image" + "I Invert & change image", + "s Slice", + "S Slice and change image" ]; const shortcuts = [