No.180 · Backgrounds· New
Velvet Grain
A slow whorl of colour on near-black under a heavy, living film grain — the look of dark velvet photographed on fast film. The pointer shifts the whorl's centre. A background only, with no text of its own.
The prompt
Written for the variant you picked above: Oxblood
Write a WebGL1 full-screen fragment shader background (no libraries): a slow whorl of colour on near-black under heavy film grain. Centre polar coordinates a little left of the middle (the pointer nudges the centre). Bands wind around it: sin(7.5r − θ + w − 0.1t), where w is soft fBm (± 1.6) so the whorl is never a perfect spiral, plus a gentler diagonal sine; band = smoothstep(0.05, 1, 0.75·a + 0.3·b), faded out right at the centre and slightly towards the far edges. Mix the ground towards the dye colour by the band, and vignette the corners. Then the grain: per-pixel hash noise re-seeded every frame, added as luminance (amount × (0.35 + band)) and as colour in the dye's hue inside the bands, so the colour itself looks grainy. Render at full resolution so the grain stays sharp. 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 — Oxblood (oxblood): Dark red on near-black: bg #070405, dye #7a1515, grain 0.14. 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 shift the whorl. Motion: The whorl turns slowly and the grain crawls every frame. Reduced motion draws one still, grainy frame. Accessibility: Decorative and hidden from assistive tech. Very dark overall, so white text reads well anywhere. 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 pointer response on touch; the whorl keeps turning. 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 shift the whorl.
- Motion
- The whorl turns slowly and the grain crawls every frame. Reduced motion draws one still, grainy frame.
- Accessibility
- Decorative and hidden from assistive tech. Very dark overall, so white text reads well anywhere.
- 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 pointer response on touch; the whorl keeps turning.