243 lines
6.3 KiB
Svelte
243 lines
6.3 KiB
Svelte
<svelte:head>
|
|
<title>Javascript Audio Visualizer</title>
|
|
</svelte:head>
|
|
|
|
<!-- Sound Visualizer Animation -->
|
|
<div class="animation_container">
|
|
<div class="animation_inner">
|
|
<div class="" id="sound_visualizer_canvas"></div>
|
|
<div class="branding overlay">WompMacho</div>
|
|
<div class="logo overlay"
|
|
style="background: url('img/WompLogo.png'); height: 100%; width: 100%; background-size: 30%; background-repeat: no-repeat; background-position: center;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr>
|
|
|
|
<h1>Audio Visualizer</h1>
|
|
|
|
<p>
|
|
A Javascript web application utilizing the P5.js library to
|
|
create a visual interpretation of audio. This takes input
|
|
via microphone or audio being played on client webpage and uses the
|
|
amplitude of the frequencies to animate lines that is
|
|
translated into little circles.
|
|
</p>
|
|
<p>
|
|
These circles change color
|
|
based on the amplitude and fade to alpha when levels are
|
|
lowered. There is additional CSS animations assisting in the
|
|
coloring/opacity of the brand name and size manipulation to
|
|
give the “pulse effect”.
|
|
</p>
|
|
|
|
<hr>
|
|
|
|
<h5>
|
|
Click on page to enable permissions and allow for audio
|
|
input.
|
|
</h5>
|
|
|
|
<style>
|
|
h1{
|
|
font-size: x-large;
|
|
margin: 1em;
|
|
}
|
|
|
|
hr{
|
|
background-color: red;
|
|
max-width: 20vw;
|
|
}
|
|
|
|
p{
|
|
margin: 1em;
|
|
border-radius: 5px;
|
|
padding: 1em;
|
|
background-color: #333333;
|
|
}
|
|
|
|
h5{
|
|
font-size: smaller;
|
|
max-width: 40vw;
|
|
margin: auto;
|
|
text-align: center;
|
|
}
|
|
|
|
.overlay {
|
|
position: absolute;
|
|
}
|
|
|
|
/* -- wrapper -- */
|
|
.animation_inner {
|
|
height: 100%;
|
|
width: 100%;
|
|
object-fit: cover;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1;
|
|
font-size: 3.5vw;
|
|
animation: brand_name 10s ease infinite alternate;
|
|
}
|
|
|
|
/* --branding -- */
|
|
.branding {
|
|
font-family: "Viner Hand ITC";
|
|
color: white;
|
|
width: 100%;
|
|
display: inline-block;
|
|
text-align: center;
|
|
z-index: 5;
|
|
}
|
|
|
|
/* -- logo -- */
|
|
.logo {
|
|
position: absolute;
|
|
z-index: 4;
|
|
animation: size-pulse 15s infinite;
|
|
}
|
|
|
|
.animation_container {
|
|
height: 40vh;
|
|
width: 40vw;
|
|
display: flex;
|
|
position: relative;
|
|
margin: 0 auto;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
@keyframes brand_name {
|
|
0% {
|
|
color: #000;
|
|
text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #228DFF;
|
|
}
|
|
|
|
50% {
|
|
color: white;
|
|
text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228DFF;
|
|
}
|
|
|
|
100% {
|
|
color: white;
|
|
text-shadow: 0 0 5px #000, 0 0 10px #000, 0 0 15px #000, 0 0 20px #228DFF;
|
|
}
|
|
}
|
|
|
|
@keyframes size-pulse {
|
|
0% {
|
|
transform: scale(0.9);
|
|
}
|
|
|
|
50% {
|
|
transform: scale(1);
|
|
}
|
|
|
|
100% {
|
|
transform: scale(0.9);
|
|
}
|
|
}
|
|
|
|
#sound_visualizer_canvas{
|
|
height: 100% !important;
|
|
width: 100% !important;
|
|
}
|
|
|
|
</style>
|
|
|
|
<script>
|
|
import { onDestroy } from 'svelte'
|
|
import { onMount } from "svelte";
|
|
|
|
let mic, fft, myp5;
|
|
|
|
onMount(async () => {
|
|
const container = document.getElementById('sound_visualizer_canvas');
|
|
const p5Module = await import("p5");
|
|
window.p5 = p5Module.default;
|
|
await import("p5/lib/addons/p5.sound");
|
|
|
|
let width, height;
|
|
width = container.offsetWidth;
|
|
height = container.offsetHeight;
|
|
|
|
const sketch = (sketch) => {
|
|
sketch.setup = () => {
|
|
|
|
// Set Color Mode
|
|
sketch.colorMode(sketch.HSB);
|
|
// Make work in degrees for circle
|
|
sketch.angleMode(sketch.DEGREES);
|
|
|
|
// Set Smoothing, bar count, dimmensions
|
|
var smoothing = 0.8;
|
|
var bands = 256;
|
|
|
|
sketch.createCanvas(width, height);
|
|
|
|
// Create an Audio input
|
|
mic = new p5.AudioIn();
|
|
console.log('Mic Started');
|
|
|
|
// Fast Fourier Transform (apmlitude at various frequencies)
|
|
fft = new p5.FFT(smoothing, bands);
|
|
fft.setInput(mic);
|
|
|
|
// start the Audio Input.
|
|
// By default, it does not .connect() (to the computer speakers)
|
|
mic.start();
|
|
};
|
|
|
|
sketch.draw = () => {
|
|
sketch.clear();
|
|
resetSketch();
|
|
}
|
|
|
|
function resetSketch(){
|
|
width = container.offsetWidth;
|
|
height = container.offsetHeight;
|
|
// Analyze the spectrum and gives array
|
|
var spectrum = fft.analyze();
|
|
|
|
// Move to Center
|
|
sketch.translate(width / 2, height / 2);
|
|
|
|
for (var i = 0; i < spectrum.length; i++) {
|
|
var angle = sketch.map(i, 180, spectrum.length, 0, 250);
|
|
var amplitude = spectrum[i];
|
|
|
|
var radius = sketch.map(amplitude, 0, 360, Math.sqrt(width * height) / 4, Math.sqrt(width * height) / 2, true);
|
|
var x = radius * sketch.cos(angle);
|
|
var y = radius * sketch.sin(angle);
|
|
//noStroke();
|
|
|
|
// draw bars
|
|
var e1 = sketch.line(x, y, x, y);
|
|
var e2 = sketch.line(y, x, y, x);
|
|
|
|
// Rotate
|
|
e1.rotate(16);
|
|
e2.rotate(16);
|
|
//rotate(radius/PI);
|
|
sketch.strokeWeight(13);
|
|
sketch.stroke(sketch.color(sketch.map(amplitude, 0, 255, 0, 255, true), sketch.map(amplitude, 0, 255, 200, 255, true), sketch.map(amplitude, 0, 255, Math.random(), 255, true), amplitude));
|
|
}
|
|
}
|
|
|
|
sketch.windowResized = () => {
|
|
sketch.resizeCanvas(width, height);
|
|
resetSketch();
|
|
}
|
|
};
|
|
|
|
myp5 = new p5(sketch, container);
|
|
});
|
|
|
|
onDestroy(() => {
|
|
mic.stop();
|
|
myp5.remove();
|
|
console.log('Mic Stopped');
|
|
});
|
|
|
|
</script> |