REFERENCE
- Gallery page: https://magpui.com/en/i/grass-shader-gallery-d9c2ca
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/grass-shader-gallery-d9c2ca/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/grass-shader-gallery-d9c2ca/clip.mp4
- Original post: https://x.com/MSchwaibold/status/2112573858754494746 by @MSchwaibold
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: Build a mobile procedural-terrain gallery component. Its initial view is a tight collage of grassy landscape previews on a pale warm canvas. Selecting one opens a large rounded portrait shader preview, with tiny terrain swatches underneath and a compact Wind control near the lower edge. Fine green blades cover rolling mounds and sway in patches; another visible preset has warm sandy-brown relief. Do not recreate the filmed phone, hand or room, only the app content.
DESIGN SYSTEM: Target a 390px-wide mobile view. Use a pale off-white #f7f0ef background, 16px side margins and approximately 8px gaps in the collage. Make uneven-height preview tiles with around 12px corner radii. In the expanded state the field occupies roughly 340 by 570px, with 18px corners. The camera looks obliquely down over soft rolling terrain rather than presenting a flat lawn. Estimate grass colors at #b6ca44, #71872e and #42572b, with darker valleys and bright yellow-green tips; use #ba8759 and #d8ac7d for the sandy preset. Place a small dark translucent pill label at the upper left of the field and a centered row of approximately five miniature terrain swatches near its bottom edge, each about 20 by 30px with narrow pale borders. Keep interface type neutral sans serif at 11-13px. Avoid extra cards, marketing copy and large control sheets.
MOTION: Selecting a gallery tile expands it into the portrait detail view; implement a 380ms position/size/radius transition, delay 0ms, cubic-bezier(0.22,1,0.36,1). Grass should sway as asynchronous patches, with bases fixed and tips following low-frequency traveling waves. Suggested recreation timings: a 2800ms primary cycle and 1300ms secondary ripple with sinusoidal easing approximated by cubic-bezier(0.37,0,0.63,1), phase offsets derived from world position. Changing the Wind input damps amplitude and speed over 180ms, delay 0ms, cubic-bezier(0.22,1,0.36,1). Swatch selection swaps terrain shading over 250ms, delay 0ms, cubic-bezier(0.4,0,0.2,1). These are proposed implementation timings, not measured source timings.
SECTIONS: Compact multi-tile gallery; selected full-size terrain preview; tiny preset label; thumbnail swatch row; lower Wind range control. Support gallery, expanded, selected-swatch and slider-drag states. Do not add unobserved Scale or Rotate controls. The green preset needs visible individual fine blades and shadowed mounds, while the brown variant retains a soft relief surface.
IMPLEMENTATION: Use Three.js instanced tapered grass blades with custom vertex-shader wind over a seeded low-frequency height field. Add variation in height, hue and bend, and use a simple shaded noise surface for the brown preset. Use HTML buttons and a labelled range input above the canvas, with visible focus states, arrow-key adjustment and keyboard tile activation. Cap DPR at 1.5, start with approximately 18000 blades, avoid per-blade JavaScript updates and pause rendering offscreen. Under prefers-reduced-motion render a still field and use immediate state changes; provide a static fallback if WebGL is unavailable.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, components and fonts; map estimated colors to the closest existing tokens. Never copy logos, brand names, photos or illustrations from the original. Use placeholders or procedurally generated terrain previews.
SUCCESS CHECK:
- The gallery opens into a rounded mobile field with small swatches, without recreating the physical phone or background.
- Fine blades follow the mounds and sway in patches, while their bases remain rooted.
- Presets and Wind work by keyboard, and reduced-motion mode has no continuous animation.