🤖 AI
Here’s a complete visualizer implementation with 32 pulsing vertical bars, smooth noise-based motion, a purple→cyan gradient, and mirrored reflections.
---
```html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>p5.js Music Visualizer</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Load p5.js core library -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
<!-- Your sketch -->
<script src="sketch.js"></script>
</body>
</html>
```
```css
/* style.css */
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #050511; /* dark background behind canvas */
}
canvas {
display: block;
}
```
```js
// sketch.js
// Simple music visualizer with 32 vertical bars, smooth noise motion,
// purple→cyan gradient, and mirrored reflection.
const NUM_BARS = 32;
let barColors = [];
function setup() {
createCanvas(windowWidth, windowHeight);
rectMode(CENTER);
noStroke();
colorMode(RGB);
// Precompute a horizontal gradient from purple to cyan for the bars
// https://p5js.org/reference/#/p5/lerpColor
const purple = color(180, 50, 255);
const cyan = color(0, 255, 255);
for (let i = 0; i < NUM_BARS; i++) {
const t = i / (NUM_BARS - 1);
barColors[i] = lerpColor(purple, cyan, t);
}
}
function draw() {
// Dark background
// https://p5js.org/reference/#/p5/background
background(5, 5, 18);
const centerY = height * 0.5;
const sidePadding = width * 0.08;
const usableWidth = width - sidePadding * 2;
const step = usableWidth / NUM_BARS;
const barWidth = step * 0.6;
// Time parameters for smooth motion
const t = frameCount * 0.02;
// Global "beat" that makes everything pulse together
// https://p5js.org/reference/#/p5/sin
const beatPhase = frameCount * 0.15; // controls pulse speed
let globalBeat = map(sin(beatPhase), -1, 1, 0.5, 1.4); // 0.5–1.4
// https://p5js.org/reference/#/p5/map
for (let i = 0; i < NUM_BARS; i++) {
const xCenter = sidePadding + step * i + step * 0.5;
// Smooth per-bar variation using noise and a local sine oscillator
// https://p5js.org/reference/#/p5/noise
const noiseVal = noise(i * 0.3, t); // 0..1
const localOsc = (sin(t + i * 0.4) + 1) * 0.5; // 0..1
// Combine noise, local oscillation, and global beat
let amplitude = (noiseVal * 0.7 + localOsc * 0.3) * globalBeat; // up to ~1.4
// Map amplitude to bar height
const barHeight = map(
amplitude,
0, 1.4,
height * 0.08, // minimum height
height * 0.45 // maximum height
);
// Pulse brightness with the beat
const baseColor = barColors[i];
let pulseStrength = map(globalBeat, 0.5, 1.4, 0.7, 1.2);
pulseStrength = constrain(pulseStrength, 0.7, 1.2);
let r = red(baseColor) * pulseStrength;
let g = green(baseColor) * pulseStrength;
let b = blue(baseColor) * pulseStrength;
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
// Top bar (above the center line)
const topHeight = barHeight;
const topCenterY = centerY - topHeight * 0.5;
fill(r, g, b);
rect(xCenter, topCenterY, barWidth, topHeight, barWidth / 2);
// Reflection (below the center line)
const reflectionHeight = barHeight * 0.7;
const reflectionCenterY = centerY + reflectionHeight * 0.5;
fill(r, g, b, 90); // semi-transparent reflection
rect(xCenter, reflectionCenterY, barWidth, reflectionHeight, barWidth / 2);
}
// Fade out the reflection towards the bottom with a gradient mask
const ctx = drawingContext; // https://p5js.org/reference/#/p5/drawingContext
const gradient = ctx.createLinearGradient(0, centerY, 0, height);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, 'rgba(0,0,0,0.9)');
ctx.fillStyle = gradient;
ctx.fillRect(0, centerY, width, height - centerY);
}
function windowResized() {
// https://p5js.org/reference/#/p5/resizeCanvas
resizeCanvas(windowWidth, windowHeight);
}
```
You can tweak these for different feels:
- `NUM_BARS` for more/less bars
- `beatPhase` multiplier (`0.15`) to speed up or slow down the pulse
- Height ranges (`height * 0.08` / `height * 0.45`) to change how tall they get.