No.174 · Backgrounds· New
Storm Veil
Smoke rolling through a storm: three layers of warped noise make deep folds and drifting veils, with fine silky strands drawn along the currents. A slow eddy turns around the pointer. Comes dark or pale. A background only, with no text of its own.
The prompt
Written for the variant you picked above: Midnight
Write a WebGL1 full-screen fragment shader background (no libraries): rolling storm smoke, seen flat-on. Take the position in screen heights × 1.15 and domain-warp it twice (Inigo Quilez style): q = two fBm lookups of p drifting in opposite directions; r = two fBm lookups of p + 4q; the smoke density f = fBm(p + 3.6r). Five octaves of quintic value noise with a rotation between octaves keep it free of grid artefacts. Turn the density into cover with smoothstep(cover, cover + 0.32, f), where cover sets how much of the frame is smoke and how much is open void; mix void → body colour by it, then towards a light colour where f is highest. Draw silky strands along the currents: pow(1 − |sin((2r.x + q.y) × 14)|, 10), added faintly inside the smoke and more strongly near its thin edges. The pointer stirs a slow eddy: rotate the position around it by up to 1.3 radians, falling off as a Gaussian. Everything drifts slowly (time × 0.035). Render through a small WebGL1 harness: a full-screen triangle, the device pixel ratio capped at 2 and scaled down (and about 30fps) on touch, paused offscreen and in hidden tabs, one still frame under reduced motion, the pointer eased in with a slow lerp and released when it leaves, and a CSS gradient fallback without WebGL. Add a little per-pixel noise so the gradients never band. An optional fade prop softens the bottom edge into the ground colour: a gradient to the ground plus a backdrop blur masked to grow towards the edge. Children sit above the canvas. Selected variant — Midnight (midnight): Navy smoke on near-black, mostly open void: void #010209, body #323e62, light #a3b4dd, cover 0.29. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Move the pointer to stir a slow eddy in the smoke. Motion: The folds drift and turn slowly. Reduced motion draws one still frame. Accessibility: Decorative and hidden from assistive tech. The dark looks suit white text; the pale look is mid-toned, so give text a scrim or a solid panel. Responsive behavior: Fills its container at any aspect ratio; device pixel ratio capped at 2. The optional fade softens the bottom edge into the ground colour. Touch: No eddy on touch; the smoke keeps drifting. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.
Notes
- Interaction
- Move the pointer to stir a slow eddy in the smoke.
- Motion
- The folds drift and turn slowly. Reduced motion draws one still frame.
- Accessibility
- Decorative and hidden from assistive tech. The dark looks suit white text; the pale look is mid-toned, so give text a scrim or a solid panel.
- Responsive
- Fills its container at any aspect ratio; device pixel ratio capped at 2. The optional fade softens the bottom edge into the ground colour.
- On touch
- No eddy on touch; the smoke keeps drifting.