Image generation
Shows a picture taking shape while the model works, with the prompt, progress and a Regenerate button.
Loading preview…
Install
- 1
Run this command in your Tailwind CSS project. It adds
components/ai/image-generation-noise.tsxand installs its dependencies.$ npx shadcn@latest add https://gradientdeck.com/ai-components/r/image-generation-noise.json
Build image-generation progress and regenerate controls →
Usage & API
Example
import { ImageGenerationNoise } from "@/components/ai/image-generation-noise"
<ImageGenerationNoise
prompt="…"
progress={1}
status="generating"
/>Props ImageGenerationNoise
| Prop | Type & description | Required |
|---|---|---|
prompt | string | Required |
progress | number0–1 | Required |
status | "generating" | "done" | Required |
onRegenerate | () => void | Optional |
seed | number | Optional |
palette | Palette | Optional |
steps | number | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
Out of noise covers the landscape with a pixelated colour grain painted on a 160 by 90 canvas and scaled up. The grain keeps repainting about twenty times a second while the card is generating and on screen, and it stops when status is done or motion is reduced. Opacity of that grain follows progress, and the SVG underneath is blurred and slightly desaturated, then sharpens as the fraction climbs. The pill reads Denoising with the current step and the step total, defaulting to 30 steps, beside a small pinging dot. A three-pixel gradient bar runs along the bottom and scales with progress. At the end the pill swaps to Done with a sparkle. The accessible name during the run is the step count, and afterward it is the prompt. Regenerate restarts the demo's clock and picks the next palette.
Example
import { ImageGenerationBlur } from "@/components/ai/image-generation-blur"
<ImageGenerationBlur
prompt="…"
progress={1}
status="generating"
/>Props ImageGenerationBlur
| Prop | Type & description | Required |
|---|---|---|
prompt | string | Required |
progress | number0–1 | Required |
status | "generating" | "done" | Required |
onRegenerate | () => void | Optional |
seed | number | Optional |
palette | Palette | Optional |
size | string | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
Blur to sharp keeps the whole landscape in frame and pulls it into focus. Progress is snapped into twelve visible passes, and a blur of up to 28 pixels eases off across those passes, with a little extra saturation and scale at the start. A large percent sits in the middle with the line Sharpening details, then both leave when generating ends. The corner pill shows the size string while the run is active, defaulting to 1536 by 864, and switches to Ready plus that size when status is done. A dark veil over the picture fades as progress rises. Reduced motion skips the blur filter and instead drops the picture's opacity while generating. The center percent still counts. The prompt and the disabled-while-running Regenerate button match the other single-image variants.
Example
import { ImageGenerationScan } from "@/components/ai/image-generation-scan"
<ImageGenerationScan
prompt="…"
progress={1}
status="generating"
/>Props ImageGenerationScan
| Prop | Type & description | Required |
|---|---|---|
prompt | string | Required |
progress | number0–1 | Required |
status | "generating" | "done" | Required |
onRegenerate | () => void | Optional |
seed | number | Optional |
palette | Palette | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The scan line reveals the landscape from top to bottom. Before the line arrives, the frame is a quiet field of dots with a soft coloured glow near the bottom. Progress drives a clip, so the finished portion grows downward, and a luminous band rides that edge: a thin gradient stroke, a wash above it, and a taller tint below. The pill reads Rendering and the percent. When status is done the clip is fully open, the band is gone, and the pill says Done. Reduced motion does not clip. It fades the whole picture in with progress instead, and it hides the moving band. The demo eases the clock so the start is quicker than the finish, but the component itself uses the progress number you pass, with no easing of its own. There is no size readout on this variant.
Example
import { ImageGenerationGrid } from "@/components/ai/image-generation-grid"
<ImageGenerationGrid
prompt="…"
progress={1}
status="generating"
/>Props ImageGenerationGrid
| Prop | Type & description | Required |
|---|---|---|
prompt | string | Required |
progress | number0–1 for the whole batch | Required |
status | "generating" | "done" | Required |
onRegenerate | () => void | Optional |
seed | number | Optional |
paletteOffset | numberIndex into the palette list for the first tile; the others follow. | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The grid splits the same 16:9 card into four tiles, two by two, with a small gap and a different corner radius on each tile. One progress value covers the batch. Each tile starts a little later than the one before it and then sharpens on its own, blurring and scaling down as its local fraction rises. Until a tile starts, a sheen sweeps across a flat placeholder. A tiny percent sits in the tile's lower right until that tile hits done. The shared pill counts how many of the four are ready, then reads 4 results with a sparkle. Regenerate is still one button for the whole card, disabled until every tile has finished. paletteOffset picks the first palette and the other three follow. Grain is turned off on these tiles so the small frames stay legible. Tiles are not selectable. Choosing among finished pictures is a different component.
Choosing a layout
Use it when the wait is long enough that a bare spinner throws away the prompt the person just wrote. A diffusion-style job, a slow upscale, or a batch of four all fit, because the card is built around a fraction you already have. Keep the same card mounted and update progress. Remounting resets nothing inside the component except the local animation clock in the demo. Your own timer, polling loop, or stream of step events should own that clock. The demo's loop is only there so the preview finishes in about five seconds.
Switch to Image results once several finished pictures exist and someone needs to choose, upscale, vary, or download one. Switch to Before and after when the question is what an edit changed, and to Edit region when the person must paint the area that should change. Video generation is the sibling for a clip that renders frame by frame and then plays. This card is the wait before any of those tools. It is a poor fit for a chat bubble that only needs a one-line status, and it is the wrong surface if you already have a final bitmap to show at full sharpness on the first paint.
Does the card create the image?
No. Each variant draws a seeded landscape so the motion has something to reveal. You supply the prompt string, progress, and status. Seed and palette only change that stand-in artwork. A production screen can keep this layout, but the files as written do not accept an image source, a blob, or a model request.
Why is Regenerate disabled mid-run?
The button's disabled state is tied to status being generating, and the icon spins for that same stretch. onRegenerate still fires from the click once the run is done. The component does not debounce, queue, or cancel an in-flight job. If you need a cancel action, it is not on this card.