Files
old-svelte-site/src/routes/projects/audio-visualizer.svelte
wompmacho 683381ccaa minor css updates, moving all videos to django site
instances cant load mp4s for some reason, refactored to pul straight from other site
2020-11-10 09:03:00 -05:00

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>