PixelTransition
pixel-transitionTransitions between two content states through a randomized pixel curtain.
Usage
Basic usage
When hovering/focusing, a mosaic of pixels scatters in and out, switching firstContent to secondContent.
<PixelTransition
firstContent={<img src="/a.jpg" alt="" className="h-full w-full object-cover" />}
secondContent={<img src="/b.jpg" alt="" className="h-full w-full object-cover" />}
/>Grid density
gridSize The larger it is, the more delicate it is and the softer the transition is; the smaller it is, the rougher it is and the stronger the mosaic feeling is.
<PixelTransition
gridSize={12}
firstContent={<Face label="Hover" />}
secondContent={<Face label="Me" />}
/>Coarse mosaic + slow + main color pixels
gridSize turns down, animationStepDuration turns up, pixelColor goes token.
<PixelTransition
gridSize={4}
animationStepDuration={0.6}
pixelColor="var(--color-primary)"
firstContent={<Face label="pixels" />}
secondContent={<Face label="Transition" />}
/>Only advance but not retreat + Customize the aspect ratio
once stops at secondContent after activation; aspectRatio is written as CSS aspect-ratio.
<PixelTransition
once
aspectRatio="1 / 1"
firstContent={<Face label="Click me" />}
secondContent={<Face label="✓" />}
/>When to Use
Use it when a portfolio or CTA card should switch between two real content layers through a pixel-mosaic curtain. It is not a background effect: use PixelTrail for a pure pixel background, or GlareHover for pointer-driven highlighting.
Import
import { PixelTransition } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| gridSize | number | 7 | Pixel grid side length (total number of blocks gridSize²), the larger, the finer and softer |
| pixelColor | string | "var(--color-foreground)" | Pixel block coloring, token variable or currentColor is recommended |
| animationStepDuration | number | 0.3 | The duration of a single transition (seconds), half of the scatter in + half of the scatter, switching at the midpoint |
| once | boolean | false | Only advance but not retreat: stop at secondContent after activation, leave/out of focus and do not return |
| aspectRatio | string | "4 / 3" | Container aspect ratio (CSS aspect-ratio writing, such as "1 / 1", "16 / 9") |
| className | string | — | Additional class name merged onto the root element |
| style | CSSProperties | — | Passthrough to root element |
Slots
| Slot | Type | Description |
|---|---|---|
| firstContent * | ReactNode | Default (static) content, usually a picture/a piece of copy, required |
| secondContent * | ReactNode | Active content, revealed through the pixel curtain after hovering/focusing/clicking, required |
Usage Guidelines
firstContent/secondContentare required double-layer content. Both layers must be 100% full (useh-full w-full), otherwise there will be a blank space after the pixel curtain is revealed.pixelColoruses a variable prefixed with--color-(var(--color-foreground)) for the token. The bare var is not parsed under Tailwind v4. See [[hulian-token-color-var-needs-color-prefix]].- Motion driver (not gsap); direct hard cutting under reduced-motion, no scatter-in/out animation.
Related
BorderBeam · ShineBorder · GlareHover · Lens · AnimatedBeam · OrbitingCircles
Playground
<PixelTransition
gridSize={7}
animationStepDuration={0.3}
once={false}
firstContent={<img src="/a.jpg" alt="" />}
secondContent={<img src="/b.jpg" alt="" />}
/>