REFERENCE
- Gallery page: https://magpui.com/en/i/voice-reactive-liquid-ink-orb-ba3e62
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/voice-reactive-liquid-ink-orb-ba3e62/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/voice-reactive-liquid-ink-orb-ba3e62/clip.mp4
- Original post: https://x.com/aswincode/status/2116910040003084318 by @aswincode
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
BUILD: A voice-recording orb for a mobile or web app. In the middle of a pale screen floats a dark graphite sphere with a soft, smoky edge and a slightly lumpy, liquid outline. It reacts to the microphone: idle it breathes slowly, while you speak its outline wobbles and it swells with how loud you are, when you pause it holds still, and when you stop recording it settles back into a calm, almost round blob. It should feel alive but calm, like a drop of ink listening to you.
DESIGN SYSTEM: Screen background #eeedf3 with a very soft darker halo behind the orb (radial gradient #d8d7de at center to transparent at about 1.6x the orb radius). Orb diameter about 42% of the screen width (about 160px on a 390px phone), centered at about 36% of the screen height. Orb shading: core #2b2b2e, lighter smoky rim #5a5a60, a faint top-left highlight #8a8a92 at 40%, outer edge feathered over about 6px so it never has a hard line. Top-right a tiny recording label: red 6px dot #ff3b30 + 'REC 0:04' in a monospace 10px #6b6b70. Bottom control pill 300x48px, #f7f7fa, 24px radius, very soft shadow 0 8px 24px rgba(0,0,0,0.06): left a 32px round cancel button with an x icon, center a 40px black circle #0b0b0c with a white 12px stop square, right a 32px round pause button.
MOTION: (1) Idle: radius oscillates plus/minus 2% over 3200ms, ease-in-out, and the outline noise drifts slowly (noise time speed 0.15). (2) Speaking: read microphone RMS each frame, smooth it with an attack of 60ms and a release of 300ms; map loudness 0 to 1 to scale 1 to 1.12 and outline displacement amplitude 0.02 to 0.09 of the radius, noise speed 0.15 to 0.9. (3) Pause (loudness under a threshold for more than 250ms or the pause button): ease the displacement and speed to almost zero over 400ms cubic-bezier(0.22, 1, 0.36, 1) so the orb holds its shape. (4) Stop: shrink to scale 0.92 and smooth the outline to round over 700ms cubic-bezier(0.65, 0, 0.35, 1). (5) Timer ticks every second.
SECTIONS: Parts: halo, orb, recording label with timer, control pill (cancel, stop, pause). States: idle (breathing), listening (reacting), paused (frozen), stopped (settled), permission denied (orb idle and a short inline message).
IMPLEMENTATION: A fragment shader on a full-size quad (WebGL with OGL or Three.js on the web; Skia runtime shader in React Native): draw a circle whose radius is displaced by 2D simplex noise sampled around the angle, shade it with a radial gradient plus fbm smoke, and feather the edge with smoothstep. Feed uniforms uTime, uLevel and uSpeed from the Web Audio API (getUserMedia + AnalyserNode RMS). Cap devicePixelRatio at 2 and pause rendering when hidden. prefers-reduced-motion: no noise drift, only a gentle scale change with loudness. All controls are real buttons with labels and a visible focus ring.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, components and fonts; map the greys and the red to the closest existing tokens. Never copy logos, brand names, photos or illustrations from the original; use placeholders.
SUCCESS CHECK:
- Speaking makes the orb wobble and grow in proportion to loudness, and silence lets it calm down.
- Pause freezes the shape and stop settles it into a smooth round blob.
- Runs at 60fps on a phone and has a reduced-motion fallback.