2022-04-20 04:11:08 +00:00
< link rel = "stylesheet" href = "./assets/css/main.css" / >
< script src = "./assets/js/prism.js" defer > < / script >
< script src = "./assets/js/audioshowkit.js" > < / script >
2022-04-18 20:11:42 +00:00
2022-04-20 04:11:08 +00:00
< div class = "part" >
< h1 > Visualizing Music< / h1 >
< p > This is the fun part. We can use a {@link VisualizedMusicPlayer} and a {@link MusicPlaylist} to create a music player that is like {@link MusicPlayer} but with the ability to automatically fetch the current {@link Visualizer}. On top of that, it then routes that visualizer data to {@link VisualizerUpdateManager} which can be to make much more refined mappings.< / p >
This library comes with a variety of mapping tools:
< ul >
2022-04-21 07:29:03 +00:00
< li > Want to map ranges of frequency bins to width, height, and other dimensions related properties? Take a look at {@link module:mappings/numeric} and {@link module:mappings/dimensions}!< / li >
2022-04-20 04:11:08 +00:00
< li > Check out {@link module:patterns/canvas} for built in canvas patterns.< / li >
2022-04-21 07:29:03 +00:00
< li > We even do font color in the {@link module:mappings/coloring} module!< / li >
2022-04-20 04:11:08 +00:00
< / ul >
< / div >
< div class = "part" >
< h2 > Instantiation< / h2 >
< p > Exactly like when instantiating a normal music player, you will need a playlist. Other than that, it's simple.< / p >
< pre > < code class = "language-js" >
const ask = window.audioshowkit; // Get a reference to the audioshowkit stuff.
const playlist = previousPlaylist; // We are assuming you have a playlist ready.
const player = new ask.player.VisualizedMusicPlayer(playlist) // Creates a new music player with the playlist.
< / code > < / pre >
< / div >
< div class = "part" >
< h2 > Playback< / h2 >
2022-04-22 06:59:35 +00:00
< p > 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.< / p >
2022-04-20 04:11:08 +00:00
< div class = "result" >
2022-04-22 06:59:35 +00:00
< div id = "playlist-display" >
< / div >
2022-04-20 04:11:08 +00:00
< div id = "playback-ctrls" >
2022-04-18 20:11:42 +00:00
< / div >
2022-04-20 04:11:08 +00:00
< / div >
< / div >
< div class = "part" >
< h2 > Visualization< / h2 >
< p > The actual visualization can be performed in a variety of ways. We can use canvases, or even better, actual HTML elements! Remember to hit the play button above to see the mappings in effect!< / p >
< div class = "part" >
< h3 > Mapping Width< / h3 >
< p > The first one here shows mapping the width.< / p >
< div class = "result" >
< div id = "width-map-demo" style = "width: 2rem; height: 2rem; background-color: black;" > < / div >
2022-04-18 20:11:42 +00:00
< / div >
2022-04-20 04:11:08 +00:00
< p > To do this, we need to perform what's called a < strong > mapping< / strong > between a range of frequency bins, or a single frequency bin, and the width property of the < code > div< / code > 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.< / p >
< pre > < code class = "language-js" >
2022-04-22 06:59:35 +00:00
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.
2022-04-20 04:11:08 +00:00
});
< / code > < / pre >
< / div >
< div class = "part" >
< h3 > Mapping Height< / h3 >
< p > This next one does the same, except with height.< / p >
< div class = "result" style = "height: 10rem;" >
< div id = "height-map-demo" style = "width: 2rem; height: 2rem; background-color: black;" > < / div >
2022-04-18 20:51:06 +00:00
< / div >
2022-04-20 04:11:08 +00:00
< pre > < code class = "language-js" >
2022-04-22 06:59:35 +00:00
ask.mappings.dimensions.height({ // Only big difference is the function being called.
element: document.getElementById("height-map-demo"),
2022-04-20 04:11:08 +00:00
growLower: 2, // height smallest can be 2 rem, tallest can be 8 rem.
growUpper: 8,
unit: "rem",
lowerBin: 80, // Changed the bin range just for fun.
upperBin: 120,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
});
< / code > < / pre >
< / div >
< div class = "part" >
< h3 > Mapping Multiple Style Properties< / h3 >
< p > What's that? you want multiple mappings on one? Here it is!< / p >
< div class = "result" style = "height: 10rem;" >
< div id = "square-map-demo" style = "width: 2rem; height: 2rem; background-color: black;" > < / div >
2022-04-18 20:51:06 +00:00
< / div >
2022-04-20 04:11:08 +00:00
< pre > < code class = "language-js" >
const squareElemConf = { // Use an object for commonly used mappings.
2022-04-22 06:59:35 +00:00
element: document.getElementById("square-map-demo"), // Same stuff as before..
2022-04-20 04:11:08 +00:00
growLower: 0.5,
growUpper: 8,
unit: "rem",
lowerBin: 128,
upperBin: 160,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
}
2022-04-21 07:29:03 +00:00
ask.mappings.dimensions.width(squareElemConf); // Apply them easily!
ask.mappings.dimensions.height(squareElemConf);
2022-04-20 04:11:08 +00:00
< / code > < / pre >
< / div >
2022-04-23 05:10:09 +00:00
< div class = "part" >
< h3 > Mapping Font Size< / h3 >
< p > You can map font size to frequency bins as well.< / p >
< div class = "result" style = "height: 6rem;" >
< div id = "font-size-map-demo" >
Wonky text!
< / div >
< / div >
< / div >
2022-04-21 06:35:29 +00:00
< div class = "part" >
< 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 >
< div class = "result" >
2022-04-22 06:25:11 +00:00
< div id = "font-color-rgba-map-demo" >
< strong > Hello colors!< / strong >
2022-04-21 06:35:29 +00:00
< / div >
< / div >
< pre > < code class = "language-js" >
2022-04-21 07:29:03 +00:00
ask.mappings.coloring.fontColorRgba({ // Under mappings, the text module. We just want to map one of the RGBA color components...
2022-04-22 06:59:35 +00:00
element: document.getElementById("font-color-rgba-map-demo"), // The element to map (same as above examples).
2022-04-22 06:25:11 +00:00
select: "r", // Choose the red component.
2022-04-21 06:35:29 +00:00
lowerBin: 128, // All other values are what we've seen above.
upperBin: 160,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
});
< / code > < / pre >
< / div >
2022-04-23 05:10:09 +00:00
< div class = "part" >
< 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 >
2022-04-22 06:25:11 +00:00
< / div >
2022-04-23 05:10:09 +00:00
< pre > < code class = "language-js" >
ask.mappings.coloring.fontColorHsla({ // Similar to the rgba example, except now with hsla.
element: document.getElementById("font-color-hsla-map-demo"),
select: "h", // Selecting the "hue" component.
lowerBin: 200,
upperBin: 220,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
})
< / code > < / pre >
2022-04-22 06:25:11 +00:00
< / div >
< div class = "part" >
< h3 > Mapping Background Color< / h3 >
2022-04-22 06:59:35 +00:00
< p > This is kind of like the one for fonts, except, instead, rgba for background colors!< / p >
< div class = "result" >
< div id = "bg-color-rgba-map-demo" style = "width: 8rem; height: 8rem; background-color: black;" >
< / div >
< / div >
< pre > < code class = "language-js" >
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)
});
< / code > < / pre >
< p > And of course we can use hsla values too.< / p >
2022-04-22 06:25:11 +00:00
< div class = "result" >
2022-04-22 06:59:35 +00:00
< div id = "bg-color-hsla-map-demo" style = "width: 8rem; height: 8rem; background-color: black;" >
2022-04-22 06:25:11 +00:00
< / div >
< / div >
2022-04-22 06:59:35 +00:00
< pre > < code class = "language-js" >
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)
});
< / code > < / pre >
2022-04-22 06:25:11 +00:00
< / div >
2022-04-21 06:35:29 +00:00
2022-04-20 04:11:08 +00:00
< / div >
2022-04-18 20:11:42 +00:00
2022-04-20 04:11:08 +00:00
< script >
const ask = window.audioshowkit;
const playlist = new ask.player.MusicPlaylist("Awesome Music");
2022-04-18 20:11:42 +00:00
2022-04-20 04:11:08 +00:00
playlist.add("./assets/audio/XXI.mp3", "XXI", "QR");
playlist.add("./assets/audio/moments.mp3", "Moments", "Lost Identities x Robbie Rosen");
2022-04-23 06:11:01 +00:00
playlist.add("./assets/audio/pathetique.mp3", "Pathetique", "Cryvera (Beethoven Remix)");
2022-04-18 20:11:42 +00:00
2022-04-22 06:59:35 +00:00
const playlistDisp = playlist.generatePlaylistElement();
document.getElementById("playlist-display").appendChild(playlistDisp);
2022-04-20 04:11:08 +00:00
const player = new ask.player.VisMusicPlayer(playlist);
const playbackCtrlsElem = document.getElementById("playback-ctrls");
const prevElem = player.generatePreviousElement();
const playElem = player.generatePlayElement();
const nextElem = player.generateNextElement();
playbackCtrlsElem.appendChild(prevElem);
playbackCtrlsElem.appendChild(playElem);
playbackCtrlsElem.appendChild(nextElem);
2022-04-18 20:51:06 +00:00
2022-04-21 07:29:03 +00:00
ask.mappings.dimensions.width({
2022-04-22 06:59:35 +00:00
element: document.getElementById("width-map-demo"),
2022-04-20 04:11:08 +00:00
growLower: 2,
growUpper: 8,
unit: "rem",
lowerBin: 24,
upperBin: 60,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
});
2022-04-18 20:51:06 +00:00
2022-04-21 07:29:03 +00:00
ask.mappings.dimensions.height({
2022-04-22 06:59:35 +00:00
element: document.getElementById("height-map-demo"),
2022-04-20 04:11:08 +00:00
growLower: 2,
growUpper: 8,
unit: "rem",
lowerBin: 80,
upperBin: 120,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
});
2022-04-18 20:51:06 +00:00
2022-04-20 04:11:08 +00:00
const squareElemConf = {
2022-04-22 06:59:35 +00:00
element: document.getElementById("square-map-demo"),
2022-04-20 04:11:08 +00:00
growLower: 0.5,
growUpper: 8,
unit: "rem",
lowerBin: 128,
upperBin: 160,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
}
2022-04-21 07:29:03 +00:00
ask.mappings.dimensions.width(squareElemConf);
ask.mappings.dimensions.height(squareElemConf);
2022-04-18 20:11:42 +00:00
2022-04-23 05:10:09 +00:00
ask.mappings.dimensions.fontSize({
element: document.getElementById("font-size-map-demo"),
growLower: 1,
growUpper: 3,
unit: "rem",
lowerBin: 200,
upperBin: 256,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2)
});
2022-04-21 07:29:03 +00:00
ask.mappings.coloring.fontColorRgba({
2022-04-22 06:59:35 +00:00
element: document.getElementById("font-color-rgba-map-demo"),
2022-04-22 06:25:11 +00:00
select: "r",
2022-04-21 06:35:29 +00:00
lowerBin: 128,
upperBin: 160,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
});
2022-04-22 06:25:11 +00:00
ask.mappings.coloring.fontColorHsla({
2022-04-22 06:59:35 +00:00
element: document.getElementById("font-color-hsla-map-demo"),
2022-04-22 06:25:11 +00:00
select: "h",
lowerBin: 200,
upperBin: 220,
visUpdateRouter: player.visUpdateRouter,
interpolator: ask.support.easings.createEaseLinear(2.5)
2022-04-22 06:59:35 +00:00
});
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)
});
2022-04-20 04:11:08 +00:00
< / script >