# Atelier UI - Full Documentation Source: https://atelier-ui.com/docs Generated: 2026-10-01T11:32:42.374Z --- ============================================================ ## Orbit Gallery > A WebGL gallery that places images on rotating rings. Scroll to spin them, click an image to zoom in. Source file: components/background/orbit-gallery.mdx *** ## Usage All WebGL components render through [one shared canvas](/docs/getting-started/how-it-works). Add the `WebglProvider` once at the root of your app: ```tsx title="Root layout" import { WebglProvider } from "@/components/webgl-provider/webgl-provider"; export default function RootLayout({ children }) { return {children}; } ``` Then use it anywhere in your app: ```tsx const ITEMS = Array.from({ length: 20 }, (_, i) => ({ src: `https://picsum.photos/seed/atelier-${i + 1}/1200/800`, alt: "", })) ``` ### Overlays `onActiveChange` gives you the index of the opened image, or `null` when it closes. Use it to render your own overlay as regular HTML: ```tsx const [active, setActive] = useState(null) <> {active !== null && (

Image {active + 1}

)} ``` ### Post-processing The gallery renders through a [WebGL Scene](/docs/foundation/primitive/webgl-scene) layered above other content. Set `mode="texture"` to render it into post-processing instead, so effects like `FluidDistortion` apply to the rings: ```tsx ``` *** ## API | Name | Type | Default | Description | | ----------------- | --------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- | | `items` | `OrbitGalleryItem[]` | — | The images placed around the rings, as `{ src, alt }`. They repeat to fill each ring. Required. | | `radius` | `number` | `2.8` | Radius of the innermost ring, in world units. | | `rings` | `number` | `3` | Number of rings around the center. | | `ringGap` | `number` | `1.6` | Distance between two neighboring rings, in world units. | | `tileHeight` | `number` | `0.7` | Height of each image tile. Width follows from the image aspect ratio. | | `cornerRadius` | `number` | `0.08` | Corner radius of each tile, in world units. `0` keeps square corners. | | `spinSpeed` | `number` | `1` | Revolutions per minute of the innermost ring. Negative values spin the other way. | | `spinStagger` | `number` | `0.2` | Speed ratio between one ring and the next. Below `1` outer rings spin slower, above `1` faster. | | `wheel` | `boolean` | `true` | Whether the scroll wheel accelerates the spin. When `false` the wheel does nothing. | | `wheelMultiplier` | `number` | `3` | How much the scroll wheel accelerates the spin. `0` disables it. | | `revealDuration` | `number` | `2` | Duration of the reveal animation, in seconds. | | `focusDuration` | `number` | `1` | Duration of the click-to-focus zoom and the ring fade, in seconds. | | `onActiveChange` | `(index: number \| null) => void` | — | Fires with the opened image index when one opens, or `null` when none is. Use it to render your own overlay from your own data. | | `className` | `string` | — | Classes for the interaction surface the gallery renders into. Sizes the gallery, any container size works. | It also forwards [WebGL Scene](/docs/foundation/primitive/webgl-scene) props: `mode`, `priority`, `zIndex`, and `transparent`. *** ============================================================ ## Sphere Gallery > A WebGL gallery that maps images onto a sphere. Drag to look around, click an image to zoom in. Source file: components/background/sphere-gallery.mdx *** ## Usage All WebGL components render through [one shared canvas](/docs/getting-started/how-it-works). Add the `WebglProvider` once at the root of your app: ```tsx title="Root layout" import { WebglProvider } from "@/components/webgl-provider/webgl-provider"; export default function RootLayout({ children }) { return {children}; } ``` Then use it anywhere in your app: ```tsx const ITEMS = Array.from({ length: 20 }, (_, i) => ({ src: `https://picsum.photos/seed/atelier-${i + 1}/1200/800`, alt: "", })) ``` ### Overlays `onActiveChange` gives you the index of the opened image, or `null` when it closes. Use it to render your own overlay as regular HTML: ```tsx const [active, setActive] = useState(null) <> {active !== null && ( {ITEMS[active].title} )} ``` ### Post-processing The gallery renders through a [WebGL Scene](/docs/foundation/primitive/webgl-scene) layered above other content. Set `mode="texture"` to render it into post-processing instead, so effects like `FluidDistortion` apply to the sphere: ```tsx ``` *** ## API | Name | Type | Default | Description | | ---------------- | --------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `items` | `SphereGalleryItem[]` | — | The images to map onto the sphere, as `{ src, alt }`. They tile to fill the grid. Required. | | `reveal` | `boolean` | `true` | When `false`, holds the reveal animation; flip to `true` to play it (e.g. after an intro). | | `revealDuration` | `number` | `2` | Duration of the reveal animation, in seconds. | | `focusDuration` | `number` | `1` | Duration of the click-to-focus zoom, in seconds. | | `focusScale` | `number` | `1.7` | How much a tile scales up when focused. | | `mouseParallax` | `number` | `0.2` | Strength of the mouse-driven parallax tilt. `0` disables it. | | `onActiveChange` | `(index: number \| null) => void` | — | Fires with the focused image index when one opens, or `null` when none is. Use it to render your own overlay from your own data. | | `rows` | `number` | `7` | Horizontal tile rings stacked from bottom to top. Tile height follows from this. | | `columns` | `number` | `12` | Sets the width of every tile. Higher values make tiles narrower and pack more around each ring. | | `latitudeRange` | `number` | `85` | Vertical spread of the rings in degrees. | | `gap` | `number` | `0.01` | Seam between neighboring tiles, in world units. `0` makes them touch. | | `padding` | `number` | `0.03` | Even border between the tile edge and the contained image, in world units. | | `cornerRadius` | `number` | `0.02` | Tile corner rounding in world units. `0` is square. | | `tileColor` | `string \| null` | `"#F8F8F8"` | Background color of the tile behind each image, shown in the padding and around images. Set to `null` to hide it so only the image shows. | | `sphereColor` | `string` | `"#ffffff"` | Color of the sphere behind the tiles. | | `lensBlur` | `number` | `0.4` | Strength of the edge lens blur. `0` disables it; higher values blur more toward the edges. | | `fov` | `number` | `70` | Camera field of view in degrees. Narrows on click to zoom into an image. | | `className` | `string` | — | Classes for the interaction surface the gallery renders into. Sizes the gallery, any container size works. | It also forwards [WebGL Scene](/docs/foundation/primitive/webgl-scene) props: `mode`, `priority`, `zIndex`, and `transparent`. *** ============================================================ ## Spiral Gallery > An infinite carousel of images staggered along a spiraling tube that scrolls indefinitely. Source file: components/background/spiral-gallery.mdx *** ## Usage All WebGL components render through [one shared canvas](/docs/getting-started/how-it-works). Add the `WebglProvider` once at the root of your app: ```tsx title="Root layout" import { WebglProvider } from "@/components/webgl-provider/webgl-provider"; export default function RootLayout({ children }) { return {children}; } ``` Then use it anywhere in your app: ```tsx const ITEMS = Array.from({ length: 20 }, (_, i) => ({ src: `https://picsum.photos/seed/atelier-${i + 1}/1200/800`, alt: "", })) ``` You can pass fewer images than `tileCount`. The list repeats until every tile on the tube has one. ### Scroll input By default the carousel moves with the wheel. If you want it to use the real page scroll, set `input="scroll"`: ```tsx ``` ### Post-processing The gallery renders through a [WebGL Scene](/docs/foundation/primitive/webgl-scene) layered above other content. Set `mode="texture"` to render it into post-processing instead, so effects like `FluidDistortion` apply to the spiral: ```tsx ``` *** ## API | Name | Type | Default | Description | | ----------------- | ------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `items` | `SpiralGalleryItem[]` | - | The images to show, each one as `{ src, alt }`. They repeat to fill `tileCount`. Required. | | `radius` | `number` | `5` | Radius of the tube the images travel around, in world units. | | `tileHeight` | `number` | `2.45` | Height of each image, in world units. | | `tileAspect` | `number` | `1.5` | Width-to-height ratio of each image. Images are cropped to fit. | | `tileCount` | `number` | `16` | Number of images on screen at once. Items repeat if there are fewer. | | `verticalSpacing` | `number` | `0.95` | Vertical distance between one image and the next. | | `turnAngle` | `number` | `46` | Angle between one image and the next around the tube, in degrees. | | `tileRotation` | `number` | `1` | How much each image rotates on its own vertical axis as it orbits. `1` keeps images flat against the tube, `0` faces them all the same way. | | `cornerRadius` | `number` | `0.05` | Corner rounding of each image, in world units. | | `curve` | `number` | `0.1` | How much each image bends inward across its width. | | `autoScroll` | `number` | `0.1` | Speed the carousel scrolls on its own, with no input. | | `easing` | `number` | `0.1` | How long the scroll takes to settle, in seconds. Higher is slower. | | `input` | `"wheel" \| "scroll" \| "none"` | `"wheel"` | Where scrolling comes from. `"wheel"` captures the wheel over the gallery, `"scroll"` follows the page scroll, `"none"` leaves only dragging. | | `inputSpeed` | `number` | `1.1` | Multiplier on wheel and drag distance. Higher moves further per gesture. | | `drag` | `boolean` | `true` | Allow dragging the carousel with the pointer. | | `scrollSpread` | `number` | `0.5` | Extra angle added between images while scrolling. `0` keeps the spacing fixed. | | `scrollGrowth` | `number` | `0.65` | How much the radius and vertical spacing grow while scrolling. | | `lensBlur` | `number` | `0.4` | Strength of the lens pass: edge blur, RGB split and the fisheye bulge that swells while an image opens. `0` disables it; higher values blur more toward the edges. | | `autoScale` | `boolean` | `true` | Shrink the spiral on narrow viewports so it stays inside the container. | | `scale` | `number` | `1.3` | Overall size of the spiral, applied on top of `autoScale`. | | `reveal` | `boolean` | `true` | Play the mount animation, where the images start as a flat band and wrap onto themselves into the tube, turning once around. | | `revealDuration` | `number` | `2` | How long the mount animation takes, in seconds. | | `focusDuration` | `number` | `2.1` | How long the click-to-focus unwinding takes, in seconds. Sliding between two open images takes 40% of it. | | `focusScale` | `number` | `0.7` | Share of the container height the open image covers, from `0` to `1`. Lower it for more room around the row. | | `className` | `string` | - | Classes for the interaction surface the gallery renders into. Sizes the gallery, any container size works. | It also forwards [WebGL Scene](/docs/foundation/primitive/webgl-scene) props: `mode`, `priority`, `zIndex`, `transparent`, and `autoReflow`. *** ============================================================ ## Edge Bounce > A wrapper that bounces away from the cursor on hover and springs back into place. Source file: components/cursor/edge-bounce.mdx *** ## Usage Wrap the content that should bounce away from the cursor. ```tsx Photo ``` *** ## API | Name | Type | Default | Description | | ------------- | ----------- | ------- | --------------------------------------------------------------------------------------- | | `children` | `ReactNode` | — | Content to render inside the wrapper. Required. | | `className` | `string` | — | Class names applied to the wrapper. | | `pause` | `number` | `0` | Delay in seconds before springing back. | | `outDuration` | `number` | `0.35` | Duration in seconds for the wrapper moving away. | | `inDuration` | `number` | `1` | Duration in seconds for the spring-back animation. | | `bounce` | `number` | `0.3` | Bounciness of the spring-back. `0` = no overshoot, `1` = maximum oscillation. | | `distance` | `number` | `35` | Maximum pixels the wrapper moves from its origin, reached at full pointer speed. | | `rotation` | `number` | `25` | Maximum rotation in degrees, following the pointer's travel direction. `0` disables it. | *** ============================================================ ## Fluid Distortion > A GPU-accelerated fluid distortion effect that reacts to cursor movement. Source file: components/cursor/fluid-distortion.mdx *** ## Usage All WebGL components render through [one shared canvas](/docs/getting-started/how-it-works). Add the `WebglProvider` once at the root of your app: ```tsx title="Root layout" import { WebglProvider } from "@/components/webgl-provider/webgl-provider"; export default function RootLayout({ children }) { return {children}; } ``` Then use it anywhere in your app: ```tsx ``` *** ## API | Name | Type | Default | Description | | --------------------- | --------- | --------- | ----------------------------------------------------------------------------------------- | | `fluidColor` | `string` | `#b4a6ff` | Sets the fluid color. Effective only when `rainbow` is set to `false`. | | `backgroundColor` | `string` | `#070410` | Sets the background color. Effective only when `showBackground` is `true`. | | `showBackground` | `boolean` | `false` | Toggles the background color's visibility. If `false` it becomes transparent. | | `blend` | `number` | `5` | Blends fluid into the scene when `showBackground` is true. Valid range: `0.00` to `10.0`. | | `intensity` | `number` | `7` | Sets the fluid intensity. Valid range: `0` to `10`. | | `force` | `number` | `1.1` | Multiplies the mouse velocity to increase fluid splatter. Valid range: `0.0` to `20`. | | `distortion` | `number` | `0.8` | Sets the distortion amount. Valid range: `0.00` to `2.00`. | | `radius` | `number` | `0.65` | Sets the fluid radius. Valid range: `0.01` to `1.00`. | | `curl` | `number` | `0.8` | Sets the amount of the curl effect. Valid range: `0.0` to `50`. | | `swirl` | `number` | `2` | Sets the amount of the swirling effect. Valid range: `0` to `20`. | | `velocityDissipation` | `number` | `0.98` | Reduces the fluid velocity over time. Valid range: `0.00` to `1.00`. | | `densityDissipation` | `number` | `0.98` | Reduces the fluid density over time. Valid range: `0.00` to `1.00`. | | `pressure` | `number` | `0.70` | Controls the reduction of pressure. Valid range: `0.00` to `1.00`. | | `rainbow` | `boolean` | `false` | Activates color mode based on mouse direction. | *** ============================================================ ## Image Trail > Cursor trail effect that spawns images along its path. Source file: components/cursor/image-trail.mdx *** ## Usage Pass the trail items as children. They spawn along the cursor path. ```tsx const IMAGES = [ "https://picsum.photos/seed/atelier-1/1200/800", "https://picsum.photos/seed/atelier-2/1200/800", "https://picsum.photos/seed/atelier-3/1200/800", ] {IMAGES.map((src) => ( ))} ``` *** ## API | Name | Type | Default | Description | | --------------- | ----------- | ------- | ----------------------------------------------------- | | `children` | `ReactNode` | — | Items to cycle through as the cursor moves. Required. | | `spawnDistance` | `number` | `76` | Distance in pixels before spawning an item. | | `driftAmount` | `number` | `36` | How far each item drifts from its spawn point in px. | | `removeDelay` | `number` | `1.0` | Seconds before a spawned item is removed. | *** ============================================================ ## Lens Media > An SEO-friendly WebGL image or video with a cursor-following circular lens and chromatic aberration. Source file: components/cursor/lens-media.mdx *** ## Usage All WebGL components render through [one shared canvas](/docs/getting-started/how-it-works). Add the `WebglProvider` once at the root of your app: ```tsx title="Root layout" import { WebglProvider } from "@/components/webgl-provider/webgl-provider"; export default function RootLayout({ children }) { return {children}; } ``` Then use it anywhere in your app: ```tsx ``` *** ## API | Name | Type | Default | Description | | -------------- | -------------------- | --------- | ------------------------------------------------------------------ | | `type` | `"image" \| "video"` | `"image"` | Render the lens on a still image or a video. | | `src` | `string` | — | Media source. | | `alt` | `string` | — | Image alt text. Required (and only used) when `type` is `"image"`. | | `size` | `number` | `0.12` | Lens radius. | | `softness` | `number` | `0.5` | Lens edge falloff. | | `aberration` | `number` | `0.18` | Color spread width. | | `dispersion` | `number` | `35` | Color sample count. | | `refraction` | `number` | `0.4` | Inward pull strength. | | `smoothing` | `number` | `7` | Cursor damping speed. | | `segments` | `number` | `1` | Plane geometry subdivisions. | | `webglEnabled` | `boolean` | `true` | Toggle WebGL effect on/off. | It also forwards `` attributes to [WebGL Image](/docs/foundation/primitive/webgl-image) and `