Glass Gallery

v1.0.1
FreeScroll3DWebGL

An immersive 3D glass-morphic photo gallery cube that disassembles into a flat responsive image collage on scroll.

Glass Gallery

Framer Remix Link

https://framer.link/8tgW8YP

Installation

Step 1. Initialize ProjectOne-time setup

Run once in your project root to configure paths and dependencies:

npx vectorvesper init
Step 2. Add ComponentInstalls source & assets

Downloads and registers the component in your project:

npx vectorvesper add glass-gallery
Step 3. Required DependenciesAuto-installed with CLI

If installing manually or managing your package lock:

npm install three @react-three/fiber @react-three/drei gsap @gsap/react
Packages:three@react-three/fiber@react-three/dreigsap@gsap/react
Requires Tailwind CSS to be configured in your project.

Usage

Import

import GlassGallery from "@/components/vv/glass-gallery";

Usage

<GlassGallery />

WebGL — render it on the client only

On Next.js, load it with ssr: false from a Client Component, as below. Vite apps need nothing extra.

"use client";

import dynamic from "next/dynamic";

const GlassGallery = dynamic(
  () => import("@/components/vv/glass-gallery"),
  { ssr: false }
);
Tailwind CSS must be configured in your project for styles to apply correctly.

Props

Photos mounted on panes of thick glass, arranged as a block that turns as you scroll and then unfolds into a flat grid. It drifts on its own when you leave it alone and tilts toward the cursor.

<GlassGallery />

The whole scene. Fills its container, so give the parent a height.

PropTypeDefaultDescription
images*string[]Photo URLs. Required. Supply at least as many as the mode has faces, or they repeat to fill.
mode"square" | "rect" | "quad""quad"How the panes are arranged before they unfold — a cube of six, a slab of twelve, or twenty-four tiles.
cubeSizenumber0.5Overall scale of the block in the scene.
autoSpinSpeednumber0.15How fast it turns on its own when nothing is happening. 0 holds it still.
scrollSpinsnumber1.0Full turns it makes across the scroll as it unfolds.
mouseTiltIntensitynumber1.0How far it leans toward the cursor. 0 removes the tilt.
glassThicknessnumber1.3How deep each pane is. Thicker glass bends what is behind it more and reads heavier.
glassRoughnessnumber0.12Surface finish, 0–1. Low is polished; higher frosts the pane.
glassOpacitynumber0.16How solid the glass itself looks, apart from the photo on it.
glassColorstring"#ffffff"Tint of the glass.
photoOpacitynumber1.0Opacity of the photos on the panes.
hoverTransparencybooleanfalseFades the near panes on hover so you can see through to the far side of the block.
backgroundColorstring"#000000"Colour behind the scene.
galleryItemWidthnumberderived from the layoutOverrides the width of a tile once the block has unfolded into a grid.
galleryItemHeightnumberderived from the layoutThe same for height.
gridGapXnumberderived from the layoutHorizontal spacing between tiles in the unfolded grid.
gridGapYnumberderived from the layoutVertical spacing.
staticPreviewbooleanfalseRenders one still frame with no scroll handling, drifting or tilt. Use it for a thumbnail, or as the reduced-motion fallback.
childrenReact.ReactNodeRendered over the scene, for overlay type.
classNamestring""Applied to the wrapper.
styleReact.CSSPropertiesInline styles merged onto the wrapper.

Presets

PresetDescriptionKey Overrides
"square"Six panes as a cube.
"rect"Twelve panes as a slab.
"quad"Twenty-four tiles. The default, and the busiest.

<GlassGalleryOverlay />

A ready-made caption panel sized to sit over the scene. Takes no props — drop it in as a child and edit the markup.

Examples

Basic scene
import GlassGallery from "@/components/vv/glass-gallery/GlassGallery";

<div className="h-screen">
  <GlassGallery images={photos} />
</div>
A cube in frosted glass
<GlassGallery
  images={photos}
  mode="square"
  cubeSize={0.7}
  glassRoughness={0.4}
  glassColor="#cfe3e8"
  hoverTransparency
/>
Still, for a card
<GlassGallery images={photos} staticPreview />
There is no automatic reduced-motion state, but staticPreview is one: pass it when the preference is set and the scene renders as a still image with the same look.
Every pane refracts what is behind it, so quad costs noticeably more than square. If a page carries several galleries, put the ones below the fold in staticPreview.
Client component. It opens a 3D drawing context on mount — import it dynamically with ssr: false if your route renders on the server.

Source

/**
 * Glass Gallery — Vector Vesper
 * https://vectorvesper.dev/components
 *
 * Copyright (c) 2026 Vector Vesper
 * Released under the MIT License. This notice must be retained in copies and
 * substantial portions of the file. https://vectorvesper.dev/license
 */
export { default } from "./GlassGallery";
export type { GlassGalleryProps } from "./GlassGallery";
export { default as GlassGalleryOverlay } from "./GlassGalleryOverlay";
View on GitHubReport an issue