AI CSS Animations

Ferrofluid

A macro film of a mirror-black ferrofluid pool in a white porcelain dish: as a hidden magnet's field passes 18 mT the pool rises into a hexagonal crown of sharp spikes, the crown glides and wobbles, then re-forms as a ring, with a live field readout beside it.

Written and rendered by AI CSS Animations Oct 18, 2026

Type
prompt
Made with
Claude Opus 5.5 in Claude Code
Built in
three.js
Topics
3D · Shapes
What Claude made from the prompt below in Claude Code: one HTML file rendered frame by frame to video. Silent preview.

About this style

Ferrofluid is a liquid carrying magnetic nanoparticles, usually magnetite, coated so they stay suspended instead of clumping. Steve Papell developed it at NASA in the early 1960s as a way to control rocket fuel in weightlessness. Above a critical field strength its surface turns unstable and rises into a regular lattice of spikes, an effect known as the normal-field or Rosensweig instability. It now seals hard-drive spindles and cools loudspeaker coils, and its spikes are a favorite of science films and kinetic sculpture.

The prompt

Make a 10-second macro film of ferrofluid: a mirror-black pool in a white dish rises into sharp spikes over a hidden magnet, the spikes travel and ripple, then settle into a crown.

<inputs>
If I don't give you something, use the default and don't ask.
- Lab: Felloway Labs (fictional).
- Title: "Liquid, magnetic."
- Line: "12 ml of ferrofluid over a hidden magnet"
- Field: 0 to 48 mT; spikes form above 18 mT.
- Length: 10 seconds.
</inputs>

<direction>
- Palette: studio sweep #ECECEF lifting to #F7F7F9 behind the dish; table #E2E2E6; porcelain #F3F1EC; ferrofluid #060607; type #16171A, secondary #6B6E76; one accent, cobalt #2E54FF, for the field bar.
- The dish: a shallow round porcelain dish (inner radius 1.0, wall 0.07 thick and 0.16 tall, a rolled lip, a foot ring) on the table, MeshPhysicalMaterial with roughness 0.3 and clearcoat 0.6, with a soft contact shadow. The fluid fills it 0.05 deep and climbs 0.02 up the wall in a meniscus.
- The surface: a 640 × 640-segment plane over the dish (vertices beyond radius 0.995 pinned into the meniscus), displaced on the CPU every seek from a closed-form height field, then computeVertexNormals:
  - Field B(x, y, t) in mT from the hidden magnet: first a disc magnet, B0·exp(−|p − m(t)|² ÷ (2·0.28²)) around its position m(t); later a ring magnet, a Gaussian ring of radius 0.42 and width 0.12 peaking at 48 mT, plus a weaker center of 34 mT.
  - Mound: the fluid gathers toward strong field, +0.07·smoothstep(0, 40, B), with the whole level lowered by the mound's mean so the volume stays the same.
  - Spikes: sites on a hexagonal lattice 0.085 apart, centered on the magnet and moving with it (in the ring phase, 18 sites evenly on the ring plus a center crown of 7). A site's height is H = 0.17·smoothstep(18, 44, B at the site), so nothing rises below the critical 18 mT. Profile H·(1 − r/0.045)^1.8 for r < 0.045: concave flanks and sharp tips, with the top 4% of each spike rounded so no tip is a single vertex.
  - Life: tips lean back against the magnet's motion by 0.25 × its velocity and recover; when the field changes shape, each height wobbles as H·(1 + 0.12·e^(−s/0.35)·cos(2π·3.2·s)), s seconds since the change; a faint ring wave (amplitude 0.004) runs out across the pool at 0.6 units/s.
- The fluid's material: MeshPhysicalMaterial, color #060607, metalness 0, roughness 0.06, clearcoat 1, clearcoatRoughness 0.02, envMapIntensity 1.6. Ferrofluid is seen through its reflections, so the environment is the lighting: bake one with PMREMGenerator.fromScene from a white room with a large softbox above and behind the dish (about 40° up, opposite the camera, so the flat pool mirrors it as a broad white sheet), two tall strips left and right (long highlights down every spike's flanks) and a mid-grey floor. A DirectionalLight from the upper left with soft shadows (PCFSoftShadowMap, 2048) gives the dish its contact shadow. ACESFilmic. The pool must never read as a flat black hole: some reflection is always on it.
- Magnet path, all closed form: no field until 1.2 s; the disc's field rises 0 → 40 mT over 1.2–3.0 s; it glides 0.38 to the right on a gentle arc and back to center over 3.0–5.0 s; over 5.0–5.8 s the disc fades as the ring rises to 48 mT; everything settles by 6.0 s.
- Camera: fov 26, 38° above the table, aimed at the dish center, the dish filling about 70% of the frame height, centered at (1080, 560); a slow 8% push and 10° orbit across the piece, easing to rest at 8.4 s.
- Readout (HTML, lower left): "FIELD" in Fragment Mono 400, 20px, tracked 0.2em, #6B6E76, at (120, 800); the value in Fragment Mono 400, 64px, tabular, "0 mT" → "48 mT", showing the peak field, baseline at (120, 880); a 360 × 6px bar filling in cobalt at y 905 with a tick at 18 mT labeled "spikes form" in Fragment Mono 400, 20px.
- Type: title in Unbounded 500, 60px, #16171A, at (120, 130); line in Unbounded 300, 22px, #6B6E76, beneath; the lab name in Fragment Mono 400, 20px, tracked 0.2em, uppercase, #6B6E76, at (120, 1000).
- Easing: field and camera on easeInOutSine; text rises 12px as it fades in over 0.6 s on cubic-bezier(0.22, 1, 0.36, 1).
- Premium: a mirror-black liquid that exists through its reflections, spikes with concave flanks and bright tips in hexagonal order, a field you can read. Cheap: a matte black blob with straight cones stuck on, spikes that pop in by scaling.
Banned: matte or grey fluid, straight-sided cones, spikes below 18 mT, a visible magnet, color in the fluid, bloom, glow, dark backgrounds, anything flashing more than 3 times per second.
</direction>

<structure>
- 0.0–1.2s: the still pool, a black mirror holding the softbox, in its white dish on the pale table; the title and line rise in.
- 1.2–3.0s: the field climbs and the readout follows; the pool bulges into a mound; at 18 mT, about 1.9 s, the first spike rises at the center, then a hexagonal crown grows outward, wobbling as it settles.
- 3.0–5.0s: the crown glides right and back, tips leaning back as it moves, ripples spreading.
- 5.0–6.0s: the field becomes a ring: the crown sinks and a ring of 18 spikes rises around a small center crown; they wobble into order by 6.0 s.
- 6.0–8.4s: the camera eases in and around; highlights slide along the spikes.
- 8.4–10.0s: hold: still spikes on a still pool, the readout at 48 mT.
For other lengths, stretch the glide; keep at least 1 s of hold.
</structure>

<build>
- One self-contained index.html (inline CSS and JS), a 1920×1080 (16:9) stage scaled to fit the window, designed for 60fps. No image, video, texture or model files: every shape and texture is generated in code.
- window.seek(t), t in seconds, computes every visual from t alone: no CSS transitions or CSS animations, no setTimeout/setInterval, no state carried between frames, randomness only from a seeded PRNG. Anything cumulative is solved analytically from t or precomputed once at load at a fixed step. Past the end, seek clamps to the last frame.
- Without ?render in the URL, drive seek from requestAnimationFrame so it plays in a browser (loop after a 1s end hold); with ?render, don't start that loop.
- Google Fonts via <link> are fine; await document.fonts.load() for each face before defining window.seek.
- Engine: three.js as an ES module pinned to three@0.160.0 through an import map on jsDelivr (`three` and `three/addons/`). WebGLRenderer with antialias, preserveDrawingBuffer: true and setPixelRatio(window.devicePixelRatio); render once at the end of every seek. Text is HTML over the canvas.
- The height field is evaluated on the CPU in seek, each spike touching only nearby vertices (a grid lookup), then computeVertexNormals; field, magnet path, lean and wobble are closed-form functions of t.
</build>

<check>
Before showing me, step through one frame per second (t = 0…10): screenshot each and look at it. Fix overlaps, clipped or cramped text, and anything off-style or Banned. Check the fluid reads as glossy black liquid in every frame (the softbox mirrored on the pool, long highlights on every spike), spikes appear only above 18 mT and sit in hexagonal order, tips are sharp without faceting at 1280×720, the readout matches the field, and the 6 s frame and the final frame are both complete and fully lit. Confirm seek(10) and seek(11) match, so the final frame holds.
</check>

Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.

Similar prompts

More like this on the motion design inspiration board: Motion graphics inspiration3D motion design inspiration