Grant Pedersen · Product designer · New York

image / lab

Loading and reveal effects for generated images, with separate control over the wait and the transition to the result.

Product design & frontend engineering · Independent project · 2026

Designing for indeterminate AI generation waits

When an application generates an image, the wait time is unpredictable, and a sudden pop-in when the file arrives feels jarring. Standard progress bars stall at 99%, while fixed-duration animations loop awkwardly if generation runs long.

I designed and built image / lab to solve the handoff between an unknown waiting period and a deterministic reveal across 12 WebGL shader effects.

Comparing shader character without losing context

I organized the 12 effects into Pixel, Organic, and Geometric categories, including Pixel mosaic, Woven, and Soft focus. Sharing the workspace grammar from dot / lab keeps navigation and export controls familiar across both tools.

Inside the playground, switching between effects preserves the active sample photograph or user-uploaded image so designers can evaluate how different textures treat the exact same composition.

image / lab catalog filtered to Pixel effects with mosaic, noise, and dot previews.
Pixel effects in the searchable catalog.

Separating the waiting clock from the reveal clock

Early prototypes drove both the loading shimmer and the image reveal from a single timeline, which caused the shader to jump whenever an image finished loading mid-cycle. I re-architected the component around two independent clocks: a continuous waiting clock controlled by loading speed, and a normalized reveal clock controlled by reveal duration.

Changing loading speed never resets the phase, and the reveal clock only starts once the loading state ends and the image texture is decoded in memory. Even if a designer sets waiting motion to zero, the reveal transition still plays smoothly over its configured duration.

Progressive color resolution and frame scrubbing

In Pixel mosaic, cells sample the incoming image’s color palette before resolving into sharp detail, bridging the abstract waiting state and the final photograph using the same grid geometry.

Because tuning a 3-second shader by replaying it from zero is slow, I added a manual progress scrubber to inspect any point in the reveal and enabled local file uploads (processed entirely on-device) to test against real product assets.

Pixel mosaic showing blocks of image color during a mountain image reveal, with controls for progress and timing.
Scrubbing partway through the Pixel mosaic reveal.

Graceful degradation for production apps

The exported React component encapsulates the WebGL shader lifecycle, texture upload, and two-clock state machine while exposing simple loading and image props to the parent app.

Animations pause automatically when offscreen or in a background tab. If WebGL is unavailable, context is lost, or prefers-reduced-motion is enabled, the component bypasses the shader and renders the standard image element cleanly.

Interface design and code: Grant Pedersen. Liquid metal uses the color and motion settings from Jakub Antalik’s MetalFx preset.