diff --git a/src/mappings/coloring.js b/src/mappings/coloring.js index 3a7c253..9e773fd 100644 --- a/src/mappings/coloring.js +++ b/src/mappings/coloring.js @@ -22,14 +22,14 @@ import { numerical } from "./numeric.js"; */ export function backgroundColorRgba({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) { const rgbaStr = "rgba"; + const defaultColor = [0, 0, 0, 255]; select = rgbaStr.indexOf(select); if (select < 0) throw new Error("Invalid color parameter provided."); const getter = () => { - if (!element.style.backgroundColor) element.style.backgroundColor = "rgba(0, 0, 0, 255)"; - return parseColorToRgba(element.style.backgroundColor)[select]; + return (parseColorToRgba(element.style.backgroundColor) || defaultColor)[select]; }; const setter = (value) => { - const changed = parseColorToRgba(element.style.backgroundColor); + const changed = parseColorToRgba(element.style.backgroundColor) || defaultColor; changed[select] = value; if (element.style.backgroundColor.startsWith("rgb")) { element.style.backgroundColor = rgbaToCssRgba(changed); @@ -74,15 +74,15 @@ export function backgroundColorRgba({ element, select, lowerBin, visUpdateRouter */ export function backgroundColorHsla({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = undefined }) { const rgbaStr = "hsla"; + const defaultColor = [0, 0.5, 0.5, 255]; select = rgbaStr.indexOf(select); if (select < 0) throw new Error("Invalid color parameter provided."); const getter = () => { - if (!element.style.backgroundColor) element.style.backgroundColor = "hsl(0, 50%, 50%, 255)"; - return parseColorToHsla(element.style.backgroundColor)[select]; + return (parseColorToHsla(element.style.backgroundColor) || defaultColor)[select]; }; const setter = (value) => { - const changed = parseColorToHsla(element.style.backgroundColor); + const changed = parseColorToHsla(element.style.backgroundColor) || defaultColor; changed[select] = value; if (element.style.backgroundColor.startsWith("hsl")) { element.style.backgroundColor = hslaToCssHsla(changed); @@ -100,6 +100,7 @@ export function backgroundColorHsla({ element, select, lowerBin, visUpdateRouter } else if (select === "a") { upperBound = 255; } + if (isNaN(upperVal)) upperVal = upperBound; upperVal = Math.min(Math.max(0, upperVal), upperBound); lowerVal = Math.min(Math.max(0, lowerVal), upperVal); const conf = { @@ -133,14 +134,14 @@ export function backgroundColorHsla({ element, select, lowerBin, visUpdateRouter */ export function fontColorRgba({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) { const rgbaStr = "rgba"; + const defaultColor = [0, 0, 0, 255]; select = rgbaStr.indexOf(select); if (select < 0) throw new Error("Invalid color parameter provided."); const getter = () => { - if (!element.style.color) element.style.color = "rgba(0, 0, 0, 255)"; - return parseColorToRgba(element.style.color)[select]; + return (parseColorToRgba(element.style.color) || defaultColor)[select]; }; const setter = (value) => { - const changed = parseColorToRgba(element.style.color); + const changed = parseColorToRgba(element.style.color) || defaultColor; changed[select] = value; if (element.style.color.startsWith("rgb")) { element.style.color = rgbaToCssRgba(changed); @@ -185,15 +186,15 @@ export function fontColorRgba({ element, select, lowerBin, visUpdateRouter, inte */ export function fontColorHsla({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = undefined }) { const rgbaStr = "hsla"; + const defaultColor = [0, 0.5, 0.5, 255]; select = rgbaStr.indexOf(select); if (select < 0) throw new Error("Invalid color parameter provided."); const getter = () => { - if (!element.style.color) element.style.color = "hsl(0, 50%, 50%, 255)"; - return parseColorToHsla(element.style.color)[select]; + return (parseColorToHsla(element.style.color) || defaultColor)[select]; }; const setter = (value) => { - const changed = parseColorToHsla(element.style.color); + const changed = parseColorToHsla(element.style.color) || defaultColor; changed[select] = value; if (element.style.color.startsWith("hsl")) { element.style.color = hslaToCssHsla(changed); diff --git a/src/support/colors.js b/src/support/colors.js index 0bd528a..1d476f2 100644 --- a/src/support/colors.js +++ b/src/support/colors.js @@ -88,7 +88,7 @@ export function rgbaToHexRgba(rgba) { * For hex, we assume there is no alpha channel unless the hex value is not minimized. * * @param {string} color The string that contains the color information. - * @returns {number[]} an array that contains the r, g, b and a components. + * @returns {number[]|null} an array that contains the r, g, b and a components. Returns null if there was an issue parsing the input. */ export function parseColorToRgba(color) { if (color.startsWith("rgba(")) { @@ -104,14 +104,14 @@ export function parseColorToRgba(color) { } else if (color.startsWith("hsl(")) { return hslaToRgba(cssHslaToHsla(color)); } - throw new Error("Could not parse to an rgba value."); + return null; } /** * Converts a css rgb, rgba, hex, hsl(a), or rgba hex to an hsla array. * * @param {string} color The string that contains the color information. - * @returns {number[]} An array that contains the h, s, l and alpha channel components. + * @returns {number[]|null} An array that contains the h, s, l and alpha channel components. Returns null if there was an issue parsing the input. */ export function parseColorToHsla(color) { if (color.startsWith("rgba(")) { @@ -127,6 +127,7 @@ export function parseColorToHsla(color) { } else if (color.startsWith("hsl(")) { return cssHslaToHsla(color); } + return null; } /** diff --git a/tutorials/VisMusicPlayer.html b/tutorials/VisMusicPlayer.html index 6a36d0f..ea70591 100644 --- a/tutorials/VisMusicPlayer.html +++ b/tutorials/VisMusicPlayer.html @@ -23,8 +23,10 @@

Playback

-

Since the usage of playback is the same as a normal {@link module:player/MusicPlayer}, see [the MusicPlayer tutorial]{@tutorial MusicPlayer} for more information.

+

Since the usage of playback is the same as a normal {@link module:player/MusicPlayer}, see [the MusicPlayer tutorial]{@tutorial MusicPlayer} for more information. We also added the playlist display to show you which song you're listening to.

+
+
@@ -40,16 +42,15 @@

To do this, we need to perform what's called a mapping between a range of frequency bins, or a single frequency bin, and the width property of the div element. We can then define a multitude of parameters to specify how the mapping will work. Following is the code that produced the example above with comment annotations.


-            const widthElem = document.getElementById("width-map-demo"); // selecting an element.
-            ask.mappings.dimensions.width({ // the mapping function for width.
-                element: widthElem, // the element to map.
-                growLower: 2, // the minimum width
-                growUpper: 8, // the maximum width
-                unit: "rem", // the units the minimum and maximum are described in.
-                lowerBin: 24, // the lower frequency bin.
-                upperBin: 80, // the upper frequency bin.
-                visUpdateRouter: player.visUpdateRouter, // the visualizer to use (we got ours from the VisMusicPlayer).
-                interpolator: ask.support.easings.createEaseLinear(2.5) // an interpolation function to make transitions between frames cleaner.
+            ask.mappings.dimensions.width({ // The mapping function.
+                element: document.getElementById("width-map-demo"), // The element this mapping applies to.
+                growLower: 2, // The smallest value the width can be. 
+                growUpper: 8, // The largest value the width can be.
+                unit: "rem", // The unit used for the above two values.
+                lowerBin: 24, // The lower bin to map to.
+                upperBin: 60, // The upper bin to map to.
+                visUpdateRouter: player.visUpdateRouter, // The update router to use for the mapping.
+                interpolator: ask.support.easings.createEaseLinear(2.5) // The interpolation function to use.
             });
         
@@ -60,9 +61,8 @@

-            const heightElem = document.getElementById("height-map-demo"); // Only big difference is the function being called.
-            ask.mappings.dimensions.height({
-                element: heightElem,
+            ask.mappings.dimensions.height({ // Only big difference is the function being called.
+                element: document.getElementById("height-map-demo"),
                 growLower: 2, // height smallest can be 2 rem, tallest can be 8 rem.
                 growUpper: 8,
                 unit: "rem",
@@ -80,9 +80,8 @@
             

-            const squareElem = document.getElementById("square-map-demo"); // Same stuff as before..
             const squareElemConf = { // Use an object for commonly used mappings.
-                element: squareElem,
+                element: document.getElementById("square-map-demo"), // Same stuff as before..
                 growLower: 0.5,
                 growUpper: 8,
                 unit: "rem",
@@ -104,9 +103,8 @@
             
         
         

-            const fontColorRgbaElem = document.getElementById("font-color-rgba-map-demo");
             ask.mappings.coloring.fontColorRgba({ // Under mappings, the text module. We just want to map one of the RGBA color components...
-                element: fontColorRgbaElem, // The element to map (same as above examples).
+                element: document.getElementById("font-color-rgba-map-demo"), // The element to map (same as above examples).
                 select: "r", // Choose the red component.
                 lowerBin: 128, // All other values are what we've seen above.
                 upperBin: 160,
@@ -122,9 +120,8 @@
         
     
     

-        const fontColorHslElem = document.getElementById("font-color-hsla-map-demo");
         ask.mappings.coloring.fontColorHsla({ // Similar to the rgba example, except now with hsla.
-            element: fontColorHslElem,
+            element: document.getElementById("font-color-hsla-map-demo"),
             select: "h", // Selecting the "hue" component.
             lowerBin: 200,
             upperBin: 220,
@@ -135,11 +132,36 @@
 
     

Mapping Background Color

-

This is kind of like the one for fonts, except, instead, for background colors!

+

This is kind of like the one for fonts, except, instead, rgba for background colors!

-
+
+

+            ask.mappings.coloring.backgroundColorRgba({
+                element: document.getElementById("bg-color-rgba-map-demo"),
+                select: "g", // Selecting the green component this time...
+                lowerBin: 200,
+                upperBin: 220,
+                visUpdateRouter: player.visUpdateRouter,
+                interpolator: ask.support.easings.createEaseLinear(2.5)
+            });
+        
+

And of course we can use hsla values too.

+
+
+
+
+

+            ask.mappings.coloring.backgroundColorHsla({
+                element: document.getElementById("bg-color-hsla-map-demo"),
+                select: "h", 
+                lowerBin: 200,
+                upperBin: 220,
+                visUpdateRouter: player.visUpdateRouter,
+                interpolator: ask.support.easings.createEaseLinear(2.5)
+            });
+        
@@ -151,6 +173,8 @@ playlist.add("./assets/audio/XXI.mp3", "XXI", "QR"); playlist.add("./assets/audio/moments.mp3", "Moments", "Lost Identities x Robbie Rosen"); + const playlistDisp = playlist.generatePlaylistElement(); + document.getElementById("playlist-display").appendChild(playlistDisp); const player = new ask.player.VisMusicPlayer(playlist); const playbackCtrlsElem = document.getElementById("playback-ctrls"); const prevElem = player.generatePreviousElement(); @@ -160,9 +184,8 @@ playbackCtrlsElem.appendChild(playElem); playbackCtrlsElem.appendChild(nextElem); - const widthElem = document.getElementById("width-map-demo"); ask.mappings.dimensions.width({ - element: widthElem, + element: document.getElementById("width-map-demo"), growLower: 2, growUpper: 8, unit: "rem", @@ -172,9 +195,8 @@ interpolator: ask.support.easings.createEaseLinear(2.5) }); - const heightElem = document.getElementById("height-map-demo"); ask.mappings.dimensions.height({ - element: heightElem, + element: document.getElementById("height-map-demo"), growLower: 2, growUpper: 8, unit: "rem", @@ -184,9 +206,8 @@ interpolator: ask.support.easings.createEaseLinear(2.5) }); - const squareElem = document.getElementById("square-map-demo"); const squareElemConf = { - element: squareElem, + element: document.getElementById("square-map-demo"), growLower: 0.5, growUpper: 8, unit: "rem", @@ -198,9 +219,8 @@ ask.mappings.dimensions.width(squareElemConf); ask.mappings.dimensions.height(squareElemConf); - const fontColorRgbaElem = document.getElementById("font-color-rgba-map-demo"); ask.mappings.coloring.fontColorRgba({ - element: fontColorRgbaElem, + element: document.getElementById("font-color-rgba-map-demo"), select: "r", lowerBin: 128, upperBin: 160, @@ -208,13 +228,30 @@ interpolator: ask.support.easings.createEaseLinear(2.5) }); - const fontColorHslElem = document.getElementById("font-color-hsla-map-demo"); ask.mappings.coloring.fontColorHsla({ - element: fontColorHslElem, + element: document.getElementById("font-color-hsla-map-demo"), select: "h", lowerBin: 200, upperBin: 220, visUpdateRouter: player.visUpdateRouter, interpolator: ask.support.easings.createEaseLinear(2.5) - }) + }); + + ask.mappings.coloring.backgroundColorRgba({ + element: document.getElementById("bg-color-rgba-map-demo"), + select: "g", + lowerBin: 200, + upperBin: 220, + visUpdateRouter: player.visUpdateRouter, + interpolator: ask.support.easings.createEaseLinear(2.5) + }); + + ask.mappings.coloring.backgroundColorHsla({ + element: document.getElementById("bg-color-hsla-map-demo"), + select: "h", + lowerBin: 200, + upperBin: 220, + visUpdateRouter: player.visUpdateRouter, + interpolator: ask.support.easings.createEaseLinear(2.5) + }); \ No newline at end of file