Added hue font color demonstration.

This commit is contained in:
Harrison Deng 2022-04-22 01:25:11 -05:00
parent 7ac924f934
commit 93ef6251e7
2 changed files with 117 additions and 20 deletions

View File

@ -10,7 +10,7 @@ import { numerical } from "./numeric.js";
* *
* @param {object} conf The configuration of the mapping. * @param {object} conf The configuration of the mapping.
* @param {HTMLElement} conf.element The element whose text's red value should be mapped. * @param {HTMLElement} conf.element The element whose text's red value should be mapped.
* @param {string} conf.color Where r for red, g, for green, b for blue, and a for alpha. * @param {string} conf.select Where r for red, g, for green, b for blue, and a for alpha.
* @param {number} conf.lowerBin The lower bound of the bins to be mapped. * @param {number} conf.lowerBin The lower bound of the bins to be mapped.
* @param {VisUpdateRouter} conf.visUpdateRouter The visualizer update manager associated with the audio playback you would like the mapping with. * @param {VisUpdateRouter} conf.visUpdateRouter The visualizer update manager associated with the audio playback you would like the mapping with.
* @param {Function} conf.interpolator The interpolation function to use. * @param {Function} conf.interpolator The interpolation function to use.
@ -20,17 +20,17 @@ import { numerical } from "./numeric.js";
* @param {number} [conf.upperVal=0] The upper boundary of possible values for the color component (0 to 255 inclusive). * @param {number} [conf.upperVal=0] The upper boundary of possible values for the color component (0 to 255 inclusive).
* @returns {{lower: number, upper: number, listener: VisUpdateRouter~visualizerRangedUpdateListener}} The ranged listener that was added. * @returns {{lower: number, upper: number, listener: VisUpdateRouter~visualizerRangedUpdateListener}} The ranged listener that was added.
*/ */
export function backgroundColorRgba({ element, color, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) { export function backgroundColorRgba({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) {
const rgbaStr = "rgba"; const rgbaStr = "rgba";
color = rgbaStr.indexOf(color); select = rgbaStr.indexOf(select);
if (color < 0) throw new Error("Invalid color parameter provided."); if (select < 0) throw new Error("Invalid color parameter provided.");
const getter = () => { const getter = () => {
if (!element.style.backgroundColor) element.style.backgroundColor = "rgba(0, 0, 0, 255)"; if (!element.style.backgroundColor) element.style.backgroundColor = "rgba(0, 0, 0, 255)";
return parseColorToRgba(element.style.backgroundColor)[color]; return parseColorToRgba(element.style.backgroundColor)[select];
}; };
const setter = (value) => { const setter = (value) => {
const changed = parseColorToRgba(element.style.backgroundColor); const changed = parseColorToRgba(element.style.backgroundColor);
changed[color] = value; changed[select] = value;
if (element.style.backgroundColor.startsWith("rgb")) { if (element.style.backgroundColor.startsWith("rgb")) {
element.style.backgroundColor = rgbaToCssRgba(changed); element.style.backgroundColor = rgbaToCssRgba(changed);
} else if (element.style.backgroundColor.startsWith("hsl")) { } else if (element.style.backgroundColor.startsWith("hsl")) {
@ -121,7 +121,7 @@ export function backgroundColorHsla({ element, select, lowerBin, visUpdateRouter
* *
* @param {object} conf The configuration of the mapping. * @param {object} conf The configuration of the mapping.
* @param {HTMLElement} conf.element The element whose text's red value should be mapped. * @param {HTMLElement} conf.element The element whose text's red value should be mapped.
* @param {string} conf.color Where r for red, g, for green, b for blue, and a for alpha. * @param {string} conf.select Where r for red, g, for green, b for blue, and a for alpha.
* @param {number} conf.lowerBin The lower bound of the bins to be mapped. * @param {number} conf.lowerBin The lower bound of the bins to be mapped.
* @param {VisUpdateRouter} conf.visUpdateRouter The visualizer update manager associated with the audio playback you would like the mapping with. * @param {VisUpdateRouter} conf.visUpdateRouter The visualizer update manager associated with the audio playback you would like the mapping with.
* @param {Function} conf.interpolator The interpolation function to use. * @param {Function} conf.interpolator The interpolation function to use.
@ -131,17 +131,17 @@ export function backgroundColorHsla({ element, select, lowerBin, visUpdateRouter
* @param {number} [conf.upperVal=0] The upper boundary of possible values for the color component (0 to 255 inclusive). * @param {number} [conf.upperVal=0] The upper boundary of possible values for the color component (0 to 255 inclusive).
* @returns {{lower: number, upper: number, listener: VisUpdateRouter~visualizerRangedUpdateListener}} The ranged listener that was added. * @returns {{lower: number, upper: number, listener: VisUpdateRouter~visualizerRangedUpdateListener}} The ranged listener that was added.
*/ */
export function fontColorRgba({ element, color, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) { export function fontColorRgba({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = 255 }) {
const rgbaStr = "rgba"; const rgbaStr = "rgba";
color = rgbaStr.indexOf(color); select = rgbaStr.indexOf(select);
if (color < 0) throw new Error("Invalid color parameter provided."); if (select < 0) throw new Error("Invalid color parameter provided.");
const getter = () => { const getter = () => {
if (!element.style.color) element.style.color = "rgba(0, 0, 0, 255)"; if (!element.style.color) element.style.color = "rgba(0, 0, 0, 255)";
return parseColorToRgba(element.style.color)[color]; return parseColorToRgba(element.style.color)[select];
}; };
const setter = (value) => { const setter = (value) => {
const changed = parseColorToRgba(element.style.color); const changed = parseColorToRgba(element.style.color);
changed[color] = value; changed[select] = value;
if (element.style.color.startsWith("rgb")) { if (element.style.color.startsWith("rgb")) {
element.style.color = rgbaToCssRgba(changed); element.style.color = rgbaToCssRgba(changed);
} else if (element.style.color.startsWith("hsl")) { } else if (element.style.color.startsWith("hsl")) {
@ -167,3 +167,65 @@ export function fontColorRgba({ element, color, lowerBin, visUpdateRouter, inter
}; };
return numerical(conf); return numerical(conf);
} }
/**
* Maps a hsla color component of an element's font color to a certain range of frequency bins.
*
* @param {object} conf The configuration of the mapping.
* @param {HTMLElement} conf.element The element whose text's red value should be mapped.
* @param {number} conf.select Where h for hue, s, for saturation, l for lightness, and a for alpha.
* @param {number} conf.lowerBin The lower bound of the bins to be mapped.
* @param {VisUpdateRouter} conf.visUpdateRouter The visualizer update manager associated with the audio playback you would like the mapping with.
* @param {Function} conf.interpolator The interpolation function to use.
* @param {number} [conf.upperBin=undefined] The upper bound of the bins to be mapped. If left undefined, then only the bin defined by the min value is used.
* @param {boolean} [conf.reversed=true] If true, then the quieter, the greater the red value.
* @param {number} [conf.lowerVal=0] The lower boundary of possible values for the color component (0 to upperVal inclusive).
* @param {number} [conf.upperVal=0] The upper boundary of possible values for the color component (0 to 360 if conf.color is "h", 1 if conf.color is "s" or "l", and 255 if conf.color is "a").
* @returns {{lower: number, upper: number, listener: VisUpdateRouter~visualizerRangedUpdateListener}} The ranged listener that was added.
*/
export function fontColorHsla({ element, select, lowerBin, visUpdateRouter, interpolator, upperBin = undefined, reversed = false, lowerVal = 0, upperVal = undefined }) {
const rgbaStr = "hsla";
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];
};
const setter = (value) => {
const changed = parseColorToHsla(element.style.color);
changed[select] = value;
if (element.style.color.startsWith("hsl")) {
element.style.color = hslaToCssHsla(changed);
} else if (element.style.color.startsWith("rgb")) {
element.style.color = rgbaToCssRgba(hslaToRgba(changed));
} else if (element.style.color.startsWith("#")) {
element.style.color = rgbaToHexRgba(hslaToRgba(changed));
} else {
element.style.color = rgbaToHexRgba(hslaToRgba(changed)); // If we don't recognize the currently used color function, then just use hex.
}
};
let upperBound = 360;
if (select === "s" || select === "l") {
upperBound = 1;
} 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 = {
minVal: lowerVal,
maxVal: upperVal,
lowerBin: lowerBin,
upperBin: upperBin,
getter: getter,
setter: setter,
interpolator: interpolator,
visUpdateRouter: visUpdateRouter,
reversed: reversed
};
return numerical(conf);
}

View File

@ -99,15 +99,15 @@
<h3>Mapping Font Color</h3> <h3>Mapping Font Color</h3>
<p>Now for a bit more of an eccentric mapping, you can map the color of a font to the music!</p> <p>Now for a bit more of an eccentric mapping, you can map the color of a font to the music!</p>
<div class="result"> <div class="result">
<div id="font-color-map-demo"> <div id="font-color-rgba-map-demo">
<strong>Hello world!</strong> <strong>Hello colors!</strong>
</div> </div>
</div> </div>
<pre><code class="language-js"> <pre><code class="language-js">
const fontColorElem = document.getElementById("font-color-map-demo"); 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... ask.mappings.coloring.fontColorRgba({ // Under mappings, the text module. We just want to map one of the RGBA color components...
element: fontColorElem, // The element to map (same as above examples). element: fontColorRgbaElem, // The element to map (same as above examples).
color: "r", // Choose the red component. select: "r", // Choose the red component.
lowerBin: 128, // All other values are what we've seen above. lowerBin: 128, // All other values are what we've seen above.
upperBin: 160, upperBin: 160,
visUpdateRouter: player.visUpdateRouter, visUpdateRouter: player.visUpdateRouter,
@ -115,6 +115,32 @@
}); });
</code></pre> </code></pre>
</div> </div>
<p>In the same vein of mapping, we can also map HSL values. If you haven't heard of HSL values, you can read up about it <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">anywhere online really</a>, but essentially, it's another way of describing a color where a hue is used to describe a color, and then the color is adjusted by its saturation and lightness. Importantly for your case, it may make it easier to achieve the type of dynamic color mapping you're looking for (potentially when used in conjunction with any of RGBA components).</p>
<div class="result">
<div id="font-color-hsla-map-demo">
<strong>Hello more colors!</strong>
</div>
</div>
<pre><code class="language-js">
const fontColorHslElem = document.getElementById("font-color-hsla-map-demo");
ask.mappings.coloring.fontColorHsla({ // Similar to the rgba example, except now with hsla.
element: fontColorHslElem,
select: "h", // Selecting the "hue" component.
lowerBin: 200,
upperBin: 220,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
})
</code></pre>
<div class="part">
<h3>Mapping Background Color</h3>
<p>This is kind of like the one for fonts, except, instead, for background colors!</p>
<div class="result">
<div id="bg-color-map-demo">
</div>
</div>
</div>
</div> </div>
@ -172,14 +198,23 @@
ask.mappings.dimensions.width(squareElemConf); ask.mappings.dimensions.width(squareElemConf);
ask.mappings.dimensions.height(squareElemConf); ask.mappings.dimensions.height(squareElemConf);
const fontColorElem = document.getElementById("font-color-map-demo"); const fontColorRgbaElem = document.getElementById("font-color-rgba-map-demo");
ask.mappings.coloring.fontColorRgba({ ask.mappings.coloring.fontColorRgba({
element: fontColorElem, element: fontColorRgbaElem,
color: "r", select: "r",
lowerBin: 128, lowerBin: 128,
upperBin: 160, upperBin: 160,
visUpdateRouter: player.visUpdateRouter, visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5) interpolator: ask.support.easings.createEaseLinear(2.5)
}); });
const fontColorHslElem = document.getElementById("font-color-hsla-map-demo");
ask.mappings.coloring.fontColorHsla({
element: fontColorHslElem,
select: "h",
lowerBin: 200,
upperBin: 220,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
})
</script> </script>