A portrait grid that magnifies faces under the cursor
| Name | Type | Default | Description |
|---|---|---|---|
items | { src: string; alt: string; title?: string; subtitle?: string; href?: string }[] | studio portrait collection | Images for the tiles, repeated across the grid so neighbours never match. Images must allow cross-origin loading. Title and subtitle caption an opened photo; href makes opening it navigate. |
columns | number | 12 | Number of columns across the container. Rows fill the height with square cells; narrow screens get fewer columns. |
tileSize | number | 0.36 | Size of a resting tile as a fraction of its cell. Small values leave the grid airy; values near 1 make a tight mosaic. |
magnify | number | 1.5 | How much the lens spreads the grid apart at its centre. Tiles there also grow to fill their enlarged cells. |
lensSize | number | 1.3 | Radius of the lens, in cells. |
fill | number | 0.92 | How much of its cell a tile at the centre of the lens fills. The rest is the gap between enlarged photos. |
radius | number | 0.14 | Corner rounding as a fraction of the tile size. 0.5 makes circles. |
saturation | number | 0 | Colour of the tiles outside the lens, from 0 (monochrome) to 1 (full colour). Tiles in the lens are always in full colour. |
dim | number | 0.25 | How much the tiles outside the lens fade into the background. |
follow | number | 0.45 | Seconds the lens takes to catch up with the pointer. Higher values feel heavier and smoother. |
autoplay | boolean | true | When the pointer is away, the lens drifts on its own across the grid. |
autoplaySpeed | number | 1 | Speed of that drift. |
openOnClick | boolean | true | Clicking a tile opens its photo large in the centre. Click again or press Escape to put it back. |
captions | boolean | true | Show the title and subtitle of an opened photo. |
interactive | boolean | true | Let the pointer and keyboard steer the lens. The arrow keys move it tile by tile and Enter opens the tile under it. |
backgroundColor | string | "transparent" | Background of the component. Captions adapt to it. |
seed | number | 0 | Changes how the images are arranged across the grid. |
paused | boolean | false | Stops the autoplay drift. Reduced-motion users never get the drift. |
dpr | number | 2 | Maximum device pixel ratio for the canvas. |
ariaLabel | string | "Portrait grid…" | Accessible description of the grid and how to use it. |
onOpen | (item, index) => void | — | Called when a photo is opened, with null and -1 when it is put back. |
ref | { open, close, focusAt } | — | Imperative controls: open an item, close it, or move the lens to a column and row. |
children | ReactNode | — | Content centred over the grid, such as a headline. It fades out while a photo is open. |
className | string | — | Classes for the root element. It fills its parent, with a 420px minimum height. |
style | CSSProperties | — | Inline styles for the root element. |
items{ src: string; alt: string; title?: string; subtitle?: string; href?: string }[]Images for the tiles, repeated across the grid so neighbours never match. Images must allow cross-origin loading. Title and subtitle caption an opened photo; href makes opening it navigate.
studio portrait collectioncolumnsnumberNumber of columns across the container. Rows fill the height with square cells; narrow screens get fewer columns.
12tileSizenumberSize of a resting tile as a fraction of its cell. Small values leave the grid airy; values near 1 make a tight mosaic.
0.36magnifynumberHow much the lens spreads the grid apart at its centre. Tiles there also grow to fill their enlarged cells.
1.5lensSizenumberRadius of the lens, in cells.
1.3fillnumberHow much of its cell a tile at the centre of the lens fills. The rest is the gap between enlarged photos.
0.92radiusnumberCorner rounding as a fraction of the tile size. 0.5 makes circles.
0.14saturationnumberColour of the tiles outside the lens, from 0 (monochrome) to 1 (full colour). Tiles in the lens are always in full colour.
0dimnumberHow much the tiles outside the lens fade into the background.
0.25follownumberSeconds the lens takes to catch up with the pointer. Higher values feel heavier and smoother.
0.45autoplaybooleanWhen the pointer is away, the lens drifts on its own across the grid.
trueautoplaySpeednumberSpeed of that drift.
1openOnClickbooleanClicking a tile opens its photo large in the centre. Click again or press Escape to put it back.
truecaptionsbooleanShow the title and subtitle of an opened photo.
trueinteractivebooleanLet the pointer and keyboard steer the lens. The arrow keys move it tile by tile and Enter opens the tile under it.
truebackgroundColorstringBackground of the component. Captions adapt to it.
"transparent"seednumberChanges how the images are arranged across the grid.
0pausedbooleanStops the autoplay drift. Reduced-motion users never get the drift.
falsedprnumberMaximum device pixel ratio for the canvas.
2ariaLabelstringAccessible description of the grid and how to use it.
"Portrait grid…"onOpen(item, index) => voidCalled when a photo is opened, with null and -1 when it is put back.
—ref{ open, close, focusAt }Imperative controls: open an item, close it, or move the lens to a column and row.
—childrenReactNodeContent centred over the grid, such as a headline. It fades out while a photo is open.
—classNamestringClasses for the root element. It fills its parent, with a 420px minimum height.
—styleCSSPropertiesInline styles for the root element.
—