REFERENCE
- Gallery page: https://magpui.com/en/i/swaying-flower-diorama-portfolio-hero-6d4f2b
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/swaying-flower-diorama-portfolio-hero-6d4f2b/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/swaying-flower-diorama-portfolio-hero-6d4f2b/clip.mp4
- Original post: https://x.com/bedirhandogn/status/2117181167095177724 by @bedirhandogn
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 portfolio hero that is a small explorable WebGL diorama. A square, open-front white room (a shadow box seen straight on, with visible ceiling, side walls and back wall in one-point perspective) sits centered on a pure black page. Inside, a low mound of rough brown-grey dirt fills the floor; dense thin black-and-white grass blades grow out of it, and about ten tall flowers on thin black stems rise to two thirds of the room height. Most flower heads are layered white paper-like petals (dahlia / chrysanthemum shapes) with a small dark center; four or five heads are instead rendered as a red checkerboard pixel-dither halftone, as if printed. Behind the flowers, large bold red letters of the owner's name sit on the back wall, partly hidden by the stems. On the left, a tilted black-framed signboard leans into the scene with a tiny red line drawing on a white panel. Everything gently sways as if in a light breeze, and the camera answers the cursor with a subtle parallax, so the room feels alive and tactile, like a paper-craft installation. Under the box, two or three centered lines of small intro copy.
DESIGN SYSTEM: Page #000000, scene box about 52vmin wide and tall, centered horizontally with about 8vh top margin. Room walls #F2F3F4 with soft ambient-occlusion falloff into the corners (corner shade #C9CCCF), ceiling slightly brighter #F7F8F9 with a soft overhead light strip. Dirt #6E6258 to #8A7C70 with darker crevices #3A332D; a black slab #111111 base below the box. Grass blades #1A1A1A to #E6E6E6 mixed, very thin. Petals #FFFFFF with grey shading #BDBDBD; flower centers #222222. Dither flowers: red #E1192B squares on white, 4-6px cells at 1x DPR in a checkerboard or ordered Bayer pattern. Name lettering: heavy sans, red #E1192B, about 22% of the box width per letter. Intro copy below the box: 11-12px sans, #9A9A9A, key words (web, product, brand, motion) in #FFFFFF bold, a link underlined, centered, max-width 460px, line-height 1.6.
MOTION: Idle wind: each stem bends from its base with a sine sway, amplitude 2-4 degrees, period 2.8-4.2s, random phase per stem; flower heads add a small extra rotation lagging the stem by about 200ms. Grass: vertex-shader sway, amplitude 3-6% of blade height, faster period 1.6-2.4s, phase from world x position so a soft wave travels across. Cursor parallax: camera offset up to 3 degrees yaw and 2 degrees pitch toward the pointer, smoothed with lerp factor 0.06 per frame (roughly cubic-bezier(0.22, 1, 0.36, 1) feel). Hovering a flower lifts it 4px and increases its sway amplitude for 600ms. Intro: on load the room fades in from opacity 0 over 800ms cubic-bezier(0.16, 1, 0.3, 1), then flowers grow from scale 0.85 to 1 with 40ms stagger.
SECTIONS: 1) Diorama room (walls, ceiling, dirt mound, grass, flowers, red name on the back wall, leaning signboard). 2) Intro copy block under the box. States: idle (breeze), pointer move (parallax), flower hover (lift and stronger sway), reduced motion (static frame).
IMPLEMENTATION: Three.js (or React Three Fiber if the project is React). Room as an inverted box with baked or SSAO-style soft shading; grass as InstancedMesh with a custom vertex shader for sway; petals as instanced curved planes with alpha; dither flowers via a fragment shader that quantizes the petal luminance into an ordered 4x4 Bayer red/white pattern in screen space. Cap DPR at 1.75, keep grass under about 4000 instances, pause rendering when the canvas is offscreen (IntersectionObserver) or the tab is hidden. prefers-reduced-motion: render one still frame and disable parallax and sway. The canvas is decorative (aria-hidden); the intro copy and links are real HTML and keyboard focusable with a visible 2px white focus ring.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, fonts and components; map colors to the closest existing tokens. Replace the name lettering and signboard drawing with the project's own name and mark as placeholders; never copy logos, brand names, photos or illustrations from the original.
SUCCESS CHECK:
- Stems and grass sway continuously with different phases, and the camera follows the pointer by only a few degrees with smoothing.
- Some flower heads render as a crisp red pixel-dither pattern while the rest stay white and shaded.
- With prefers-reduced-motion the scene is a single still frame and the page holds 60fps on a mid-range laptop otherwise.