Skip to content
Sign in
EffectsDenoise placeholderMenu

Denoise placeholderPro

An image slot for a diffusion job: grayscale grain that converges toward a blurred low frequency field as real steps arrive, then sharpens into the finished image.

ProA 30 step diffusion job: grain converges toward a blurred latent preview as real steps arrive, then sharpens into the finished image.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/denoise-placeholder

Usage

tsx
import { DenoisePlaceholder } from "@/components/ui/chatcn/pro/denoise-placeholder"

<DenoisePlaceholder
  src={job.imageUrl}
  alt={job.prompt}
  step={job.step}
  totalSteps={job.totalSteps}
  preview={job.latentPreviewUrl}
  aspectRatio="3:2"
/>

Feed step and totalSteps from your sampler events. The grain falls as steps arrive and the field gains structure: flat gray first, the composition later. If the provider streams a latent preview, pass it as preview and the grain converges toward a blurred version of it instead of an abstract field. Set src when the job is done: the field sharpens into the picture, blends to its real colors and hands off to the <img> with no visible swap.

A slot mounted with src already set (a history item) shows the image at once, with no effect. Pass a different seed per slot so a batch of four does not flicker in sync.

Examples

States

No progress reported, early and late steps, a latent preview, a failed job, a finished image from history, a batch of four and right to left.

ProNo progress reported, early and late steps, a latent preview, a failed job, a history item and a batch of four.

Props

PropTypeNotes
srcstringThe finished image. Setting it hands the placeholder off
altstringRequired. Describes the finished image; announced once it is in
status"generating" | "done" | "error"Default: done when src is set, otherwise generating. Going back to generating starts a new job
step, totalStepsnumberThe step count the sampler reports. The most honest progress there is
progressnumber | null0 to 1, when the API reports a fraction. Leave all three out and it creeps
aspectRationumber | "3:2" | "16/9"Set it so nothing shifts when the image lands
labelReactNodeThe status chip label
showStatusbooleanShow the status chip. Default true
errorMessage, onRetryCopy for the error state (say what to do) and its Retry button
onRevealed() => voidOnce, when the finished image is fully on screen
maxPixels, rendererBacking store cap and "auto" | "webgl" | "2d"
previewstringA latent preview or partial image. The grain converges toward it
seednumberSeeds the field and the grain. Default 1
grainnumberCSS px per grain cell, snapped to device pixels. Default 2
ink, paperstringGrain tones. Default fg-subtle and inset tokens
width, height, imgClassNamePassed to the final <img>

Keyboard

KeyAction
TabReaches the pause button while the job runs, and Retry in the error state
Enter / SpacePauses or plays the grain, or retries

Accessibility

  • The frame is aria-busy while the job runs and holds a screen reader progressbar with a value text such as Step 18 of 30. Ticks are never announced.
  • A polite live region says Image ready: <alt> once the image is in, and that the job failed when it fails.
  • The status chip is decorative (aria-hidden); the progressbar carries the same facts.
  • The error state is role=alert, says how to fix the problem and has a real Retry button. Small tiles keep an icon only retry with its name.
  • Under forced-colors: active the effect hides and the plain image shows.

Motion

  • The grain flickers at 24 fps while the job runs. Its amplitude follows real progress, eased so it never runs backwards and never sits at 99.
  • The handoff is 500 ms: the blur sharpens to full resolution, then the gray tones blend to the photo's colors, then the <img> fades in over 200 ms.
  • Under reduced motion the grain changes only when progress changes, and the handoff is a 150 ms fade.
  • Offscreen and in a background tab the grain stops; the frame keeps its last picture.