SecretoCho
menu

component 01 / 28WORKINGfeatured

SC ThreeJS Audio Particles

type
Code Component
platform
Framer
last update
read time
12–16 min
license
SecretoCho Design
needs JavaScript

demo · runs with JavaScript

fig 00 · live demo, ported from SC_ThreeJSAudioParticles.tsx

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

  • three.js
  • webgl
  • glsl
  • particles
  • audio
  • analyser
  • shader
  • curl-noise
  • simplex
  • mic
  • gyro

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

  1. Drop SC-ThreeJS AudioParticles into a frame (it auto-sizes to the container).
  2. Set particleCount (start 1500–3000 on laptops).
  3. Choose bgColor / lowColor / midColor / highColor as GLSL vec3(r,g,b) values (0–1).
  4. Adjust camera: cameraZ (orbit radius), FOV, near/far.
  5. Interaction: enable Mouse (desktop) or Gyro Control (mobile).
  6. 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

nametypedefaultdescription
particleCountnumber2500Number of particles in the point cloud (higher = richer, slower)
enableMousebooleantrueEnable mouse-driven camera orbit on desktop
gyroControlbooleanfalseEnable device-orientation orbit on mobile (prompts for permission on iOS)
cameraZnumber1Camera radius/orbit distance from origin
cameraFovnumber75Perspective field of view in degrees
cameraNearnumber0.1Camera near clipping plane
cameraFarnumber5000Camera far clipping plane
bgColorstringvec3(0.0, 0.0, 0.0)Scene background color (GLSL vec3)
lowColorstringvec3(0.1, 0.4, 1.0)Color influence for low frequencies
midColorstringvec3(1.0, 0.4, 0.1)Color influence for mid frequencies
highColorstringvec3(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

SC_ThreeJSAudioParticles.tsx · lines 4–10 · 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) */

props [REF]

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.

SC_ThreeJSAudioParticles.tsx · lines 168–198 · glsl
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

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

read the CV · LinkedIn