Aperture Reveal

Snowy peaks under the Milky Way above a dark line of pines
About this component

Aperture Reveal

A Canvas 2D camera iris in front of a full-bleed photograph: machined blades in brushed dark metal, each catching the light at its own angle, with crisp overlapping seams, soft cast shadows, lit edges and fine grain, set in a turned metal ring on a matte lens body. As it opens the blades turn and retract, then the ring grows past the frame so the photo stands alone. Progress can be driven from scroll (a number or a MotionValue, read every frame without re-renders) or left to a slow open, hold and close loop. The light on the metal and the photo drift with the cursor. Blade count, colors, rotation, twist, pace and grain are props; it pauses offscreen and holds a still frame for reduced motion.

Usage

The import and the props worth knowing about, in one place.

import { ApertureReveal } from "@/components/beste/component/aperture-reveal";

<ApertureReveal className="h-[32rem] w-full" />

// Driven by scroll: pass a number from 0 (closed) to 1 (open), or a framer-motion MotionValue
const { scrollYProgress } = useScroll({ target: ref, offset: ["start start", "end end"] });

<ApertureReveal
  className="absolute inset-0"
  imageSrc="/photos/night-sky.jpg"
  imageAlt="Snowy peaks under the Milky Way"
  progress={scrollYProgress}
  blades={11}                 // 5 to 16
  bladeColor="#23201c"        // any CSS color
  highlightColor="#ffe9c7"
  twist={0.8}                 // blades turn further while opening
/>

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
imageSrcstring—Photograph behind the iris.
imageAltstring—Alt text for the photograph.
bladesnumber—Number of iris blades.
bladeColorstring—Color of the blades and the machined ring. Any CSS color.
highlightColorstring—Color of the light caught by blade edges and the ring.
bodyColorstring—Color of the lens body around the ring.
rotationnumber—Starting angle of the blades, in degrees.
twistnumber—How far the blades turn while opening, 0 to 1.
progressnumber | { get: () => number }—0 closed, 1 open with the ring gone past the frame. Leave unset to let autoplay run.
autoplayboolean—Open, hold and close on a slow loop. Defaults to on when no progress is given; when on, it wins over progress.
speednumber—Autoplay pace, 1 is the default.
grainnumber—Fine grain on the metal, 0 to 1.
interactiveboolean—Light on the metal and the photo follow the cursor.
pausedboolean—Hold the autoplay where it is.
classNamestring—
childrenReactNode—

More Media components

View all Media
A turquoise bay ringed by pines and limestone
Concrete spiral staircase shot from below
Turquoise shallows and a pebble beach seen from above
Quiet timber-clad interior
A quiet pebble beach with a wooded headland
A quiet, light-filled interior
Concrete stairwell lit from a single window
Portrait of a man in a grey sweater against a pale wall