Shattering Image Gallery Transition
See the Pen Shattering Image Gallery Transition.
Tech & Dependencies
Features
- ✓ WebGL Shaders
- ✓ Instanced Rendering
- ✓ Scroll Navigation
- ✓ Mouse Parallax
Browser Support
Core
This is a Shattering Image Gallery Transition. It utilizes the WebGL API via Three.js to deconstruct 2D images into a matrix of 3D particles. Its function is to replace standard fade or slide slideshows with a highly cinematic, physics-based explosion effect, transitioning between photographs by blowing the current image apart to reveal the next one underneath.
Specs
- Weight: Heavy. Requires Three.js and GSAP libraries, plus high-resolution image textures.
- Performance: Highly optimized. It uses
InstancedMeshand custom GLSL vertex shaders, allowing the browser to render and animate thousands of individual square fragments in a single draw call, maintaining 60 FPS. - Theming / Customization: Controlled via the
confobject in JavaScript, where you define thesizeof the shatter fragments and an array of image URLs. - Responsiveness: Re-evaluates camera aspect ratio, plane geometry, and UV mapping on window
resizeto ensure the image covers the viewport without stretching. - Web APIs: WebGL API, HTML Canvas API.
- Graceful Degradation: [!] Fails completely to a blank screen if WebGL is unsupported or JavaScript is disabled. There is no fallback HTML structure.
Anatomy
The architecture bypasses the DOM entirely, rendering directly to a <canvas> element.
- HTML/CSS (The Skeleton & Skin): A barebones, full-screen
<canvas id="canvas">. CSS removes margins and sets the cursor to a pointer. - JS (The Nervous System):
- State Management: Tracks scroll/click inputs to update the
targetProgressvariable. - Texture Loading: Preloads all images using
THREE.TextureLoaderto prevent mid-animation stuttering. - Plane Construction: Generates an
InstancedMeshgrid (plane1,plane2), mathematically calculating the required rows (ny) and columns (nx) based on viewport size. - Custom Shaders: Overrides the standard
MeshBasicMaterialvertex shader to inject custom translation (offset) and rotation matrices for the explosion physics.
- State Management: Tracks scroll/click inputs to update the
Logic
The core optimization is “Instanced UV Mapping and Custom Vertex Shaders”:
shader.vertexShader = shader.vertexShader.replace('#include <project_vertex>', `
mat3 rotMat = rotationMatrixXYZ(progress * rotation);
transformed = rotMat * transformed;
vec4 mvPosition = vec4(transformed, 1.0);
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition.xyz += progress * offset;
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;
`);
Instead of updating the x, y, z coordinates of 5,000 individual meshes in a JavaScript loop every frame (which would crash the CPU), the code passes a single progress uniform (from 0 to 1) to the GPU. The GPU shader then multiplies this uniform by a pre-calculated random offset and rotation attribute unique to each instance. The GPU executes this math in parallel for every single fragment simultaneously, resulting in a buttery-smooth explosion.
Feel
Violent, kinetic, and deeply satisfying. Scrolling the mouse wheel feels like scrubbing through a video timeline of an explosion; you can pause mid-shatter, reverse the explosion to piece the image back together, or click to blast the image toward the camera. The subtle mouse parallax (tiltX, tiltY) adds a continuous layer of depth, making the flat photographs feel like physical glass panels waiting to be broken.


