import * as THREE from 'three';
import { SimplexNoise } from 'three/addons/math/SimplexNoise.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x05060c);
const camera = new THREE.PerspectiveCamera(50, 1, 0.1, 100);
camera.position.set(0, 2.6, 5.4);
camera.lookAt(0, 0, 0);
scene.add(new THREE.AmbientLight(0x445577, 1.3));
const dl = new THREE.DirectionalLight(0xffffff, 1.1);
dl.position.set(3, 5, 3);
scene.add(dl);
const base = new THREE.Mesh(new THREE.PlaneGeometry(12, 4), new THREE.MeshBasicMaterial({ color: 0x0a0e1a }));
base.rotation.x = -Math.PI / 2;
base.position.y = -0.02;
scene.add(base);
const BARS = 28;
const geo = new THREE.BoxGeometry(0.28, 1, 0.28);
const mat = new THREE.MeshStandardMaterial({ roughness: 0.4 });
const mesh = new THREE.InstancedMesh(geo, mat, BARS);
const dummy = new THREE.Object3D();
const color = new THREE.Color();
const simplex = new SimplexNoise();
scene.add(mesh);
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
renderer.setAnimationLoop((t) => {
const time = t * 0.001;
for (let i = 0; i < BARS; i++) {
const band = i / (BARS - 1);
const bass = Math.max(0, Math.sin(time * 2.4) * 0.5 + 0.5) * Math.exp(-band * 2.5);
const n = (simplex.noise(band * 3.0, time * 1.6) + 1) * 0.5;
const mag = 0.15 + bass * 1.1 + n * 0.9 * (1.0 - band * 0.4);
dummy.position.set((i - (BARS - 1) / 2) * 0.36, mag / 2, 0);
dummy.scale.set(1, Math.max(0.05, mag), 1);
dummy.updateMatrix();
mesh.setMatrixAt(i, dummy.matrix);
color.setHSL(0.62 - band * 0.45, 0.85, 0.55 + mag * 0.12);
mesh.setColorAt(i, color);
}
mesh.instanceMatrix.needsUpdate = true;
if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true;
renderer.render(scene, camera);
});