component 01 / 28WORKINGfeatured
SC ThreeJS Audio Particles
- type
- Code Component
- platform
- Framer
- last update
- read time
- 12–16 min
- license
- SecretoCho Design
demo · runs with JavaScript
Audio-reactive WebGL particle field (Three.js) using curl/simplex-noise displacement and FFT bands for color/size, with mouse/gyro orbit camera.
SC ThreeJS Audio Particles is an audio-reactive particle field powered by Three.js and custom GLSL shaders. Particles swirl with curl-noise motion, expand and pulse to live microphone input, and color-shift across low/mid/high bands. Supports mouse orbit or gyroscope look controls and runs as a full-bleed WebGL canvas inside Framer.
Great for music heroes, landing backgrounds, VJ loops, or meditative reactive visuals.
- Visual
- Audio-Reactive
- Three.js
Main
Overview
- Built With
- React, Three.js, WebGL, GLSL, Framer Code Component API
- Layout Support
- Fully Responsive (fills container)
- Orientation
- Full-bleed canvas visualization
- Ideal Use Case
- Music visualizers, hero backgrounds, live show booths, generative art
Tags
Code comment
/** * Audio-reactive Three.js particles with GLSL curl/simplex noise. * Mouse/gyro orbit · Mic-driven uniforms for color/size/displacement. * Original anim © Jared Stanley · Framer port © SecretoCho Design, 2025 * @framerDisableUnlink * @framerSupportedLayoutWidth any * @framerSupportedLayoutHeight any */Dependencies
- Technologies
- Three.js, Web Audio API, DeviceOrientation API (optional)
- Notes
- Requires HTTPS for mic/gyro permissions; no external state managers.
Complexity
- Logic Level
- Medium–High (shaders + audio analysis)
- Runtime Cost
- Medium–High (GPU fragment/vertex + point sprites)
- Component Size
- ~6–8 KB (raw TSX + shaders)
- Notes
- Throughput scales with particleCount; tune for target devices.
Guide
Instructions
- Drop SC-ThreeJS AudioParticles into a frame (it auto-sizes to the container).
- Set particleCount (start 1500–3000 on laptops).
- Choose bgColor / lowColor / midColor / highColor as GLSL vec3(r,g,b) values (0–1).
- Adjust camera: cameraZ (orbit radius), FOV, near/far.
- Interaction: enable Mouse (desktop) or Gyro Control (mobile).
- Click once to grant mic permission and start audio reactivity.
Examples / Presets
Club Visual
- particleCount
- 3500
- cameraZ
- 1.4
- low
- vec3(0.1,0.4,1.0)
- mid
- vec3(1.0,0.4,0.1)
- high
- vec3(1.0,0.1,0.4)
Calm Ambient
- particleCount
- 1800
- cameraZ
- 1.8
- low
- vec3(0.2,0.6,0.9)
- mid
- vec3(0.2,0.9,0.6)
- high
- vec3(0.9,0.2,0.6)
Monochrome
- particleCount
- 2200
- colors
- vec3(1.0,1.0,1.0)
- bg
- vec3(0.0,0.0,0.0)
Mechanics
How it Works
- Geometry: random points on/in a sphere (cubic distribution with r = cbrt(rand)*2).
- Attributes: positions also used as normals for directional cues.
- Vertex Shader:
- Curl noise field + simplex noise → ordered + chaotic displacement.
- Audio uniforms (uAudioLow/Mid/High) modulate expansion, movement, and size.
- gl_PointSize scales with audio and perspective.
- Fragment Shader: soft circular sprite with inner glow; mixes base and audio-tinted colors.
- Audio: Web Audio AnalyserNode (fftSize=512) → frequency averages for low/mid/high bands.
- Controls: mouse maps to spherical angles; Gyro uses DeviceOrientation (permission-gated on iOS).
- Loop: requestAnimationFrame updates uniforms, camera, and renders.
Performance & Tuning
- particleCount dominates cost. Targets:
- Mobile: 1200–2200 · Laptops: 2000–4000 · Desktops: 4000–8000.
- Prefer smaller pointSize via shader (already dynamic) over more particles.
- Avoid excessive bg blur/overlays atop the canvas; they force compositing.
- Run in a container sized to need; massive full-screen on 5K displays will be heavy.
- Consider lowering analyser fftSize if you fork (256) for fewer allocations.
Compatibility & Limits
- HTTPS required for mic + sensors.
- User gesture required to start audio on Safari/iOS (first click handled).
- Works in modern evergreen browsers with WebGL; no SSR rendering.
Quality
Accessibility
- Decorative by default: wrap with aria-hidden="true" if it conveys no information.
- If used behind text, ensure sufficient contrast and avoid rapid strobe effects.
Security & Privacy
- Permissions: Mic access via getUserMedia({audio:true}); Gyro access via DeviceOrientationEvent.requestPermission() on iOS.
- Data: Audio stays in-browser; no network calls, logging, or storage.
- Hardening: Events are removed on unmount; consider disposing Three.js objects (renderer.dispose(), geometry.dispose(), material.dispose()) in a fork for long-lived pages.
Reference
Props
| name | type | default | description |
|---|---|---|---|
particleCount | number | 2500 | Number of particles in the point cloud (higher = richer, slower) |
enableMouse | boolean | true | Enable mouse-driven camera orbit on desktop |
gyroControl | boolean | false | Enable device-orientation orbit on mobile (prompts for permission on iOS) |
cameraZ | number | 1 | Camera radius/orbit distance from origin |
cameraFov | number | 75 | Perspective field of view in degrees |
cameraNear | number | 0.1 | Camera near clipping plane |
cameraFar | number | 5000 | Camera far clipping plane |
bgColor | string | vec3(0.0, 0.0, 0.0) | Scene background color (GLSL vec3) |
lowColor | string | vec3(0.1, 0.4, 1.0) | Color influence for low frequencies |
midColor | string | vec3(1.0, 0.4, 0.1) | Color influence for mid frequencies |
highColor | string | vec3(1.0, 0.1, 0.4) | Color influence for high frequencies (use GLSL vec3) |
Notes & Tips
- Use a HEX → GLSL vec3 converter for colors (values are 0–1 floats).
- For kiosk setups, lock gyroControl=false and prefer mouse to avoid noisy sensor drift.
- Camera feeling “flat”? Increase cameraZ slightly and lower FOV to 60–70.
Troubleshooting / FAQ
Nothing reacts to audio.
Click the canvas to grant mic permission; check site is served over HTTPS; verify system input level.
Movement is jittery on mobile.
Disable Gyro Control or hold device steady; sensor noise varies by hardware.
Black screen.
Ensure WebGL is enabled; try lowering particleCount.
Colors look wrong.
Provide vec3(r,g,b) with values 0–1 (e.g., vec3(1.0,0.0,0.0) for red).
Source
Header comment
/** * Audio-reactive particle system using Three.js + GLSL curl/simplex noise. * Mouse or gyroscope camera orbit; mic-driven uniforms for color/size/displacement. * The animation by [© Jared Stanley](https://codepen.io/jaredstanley) * Modified and converted to Framer by [© SecretoCho Design](https://secretocho.design), 2025 * Having Issues? [Contact Us](https://secretocho.design/help) */Key excerpt
The vertex shader’s main(): curl noise moves the points in order, simplex noise in chaos, and the three audio bands mix the two, tint the colour and size each point.
void main(){vec3 curl=curlNoise(position*0.5+uTime*0.1);float noise=snoise(position*0.5+uTime*0.2);float chaos=(uAudioLow+uAudioMid+uAudioHigh)*0.7;vec3 randomOffset=vec3(snoise(position+vec3(uTime*2.0,0.0,0.0)),snoise(position+vec3(0.0,uTime*2.0,0.0)),snoise(position+vec3(0.0,0.0,uTime*2.0)));float expansion=1.0+uAudioLow*0.5;vec3 basePosition=position*expansion;vec3 orderedMovement=curl*(0.3+uAudioMid*0.20)+normal*(noise*0.42);vec3 chaoticMovement=randomOffset*chaos*2.0;vec3 displaced=basePosition+mix(orderedMovement,chaoticMovement,chaos*0.7);displaced+=curl*sin(uTime*10.0)*uAudioHigh*0.2;vec3 baseColor=vec3(0.5+0.5*sin(curl.y+2.0),0.5+0.5*sin(uTime*1.0+curl.y),0.5+0.5*sin(uTime*0.1+curl.z+4.0));vColor=baseColor;vColor=mix(vColor,lowColor,uAudioLow*0.057);vColor=mix(vColor,midColor,uAudioMid*0.057);vColor=mix(vColor,highColor,uAudioHigh*0.057);vAudioMid=uAudioMid;vec4 mvPosition=modelViewMatrix*vec4(displaced,1.0);gl_Position=projectionMatrix*mvPosition;float size=5.0;size+=uAudioLow*1.0;size+=uAudioMid*5.0;size*=(1.0+uAudioHigh);gl_PointSize=size*(1.0 / -mvPosition.z);}`Credits
Credits
Original animation © Jared Stanley; Three.js/GLSL adaptation for Framer © SecretoCho Design (2025).
- inspired by
- Jared Stanley · codepen.io/jaredstanley
- license
- SecretoCho Design
SecretoCho Design 2025
Disclaimer
Provided “as is” for visual/UX purposes. You’re responsible for obtaining user consent for microphone/sensor usage and validating performance, accessibility, and licensing in your environment.
Proves
Hiring a design engineer?
I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.
sc@secretocho.design