Quick Start
- Keep
index.htmlandassets/together and serve the folder with any static web host or local HTTP server. No build step is required. - Replace
OFFORM, the studio introduction andhello@ofform.exampleinindex.html. The example email address cannot receive messages. - Replace the local photographs in
assets/img/, preserving filenames, or update their paths in the HTML. Each project appears in the reel, its archive entry and, for the first three, a larger study. - Deploy the folder. The contact links open an email client; there is no form or backend service.
Keep the synchronous head enhancement script, CDN tags and import map when moving the page into another project. The import map loads three.js as an ES module, then the page loads assets/script.js. If you already use three.js, supply the same window.THREE module before running the script instead of loading it twice.
Page Structure
| Section | Editing |
|---|---|
| Opening and reel | Replace the masthead, six data-warp-project entries and their project links. |
| Studio | Change the introduction, capabilities and inset photograph. |
| Project studies | Replace the large photographs and matching captions; update the archive destinations. |
| Archive | Each native <details> is a complete case note. Add text or pictures inside .project-detail. |
| Contact | Update both email links and the visible email address. |
Every animation checks for its section before initialising. Delete any section you do not need, then remove or retarget links to that section. Project links use explicit IDs rather than positional indexes. Add a reel item and its archive entry together; the reel counter updates from its content automatically.
Reel Options
Attribute on data-warp-reel |
Default here | Purpose |
|---|---|---|
data-wheel |
0 |
Keeps wheel scrolling with the page. Leave at zero for a normal portfolio site. |
data-strength |
1 |
Motion deformation, from 0 to 1.35. Zero removes the extra gesture bend. |
data-barrel |
0.4 |
Resting curvature, from 0 to 0.5. |
data-pixel-ratio |
1.5 |
Rendering resolution cap. Lower this first on slower devices. |
On desktop, the full-screen reel pins for 2.6 viewport heights of scrolling, progressing through six projects. Numbered buttons and arrows navigate to the matching scroll position. On touch screens, swipe horizontally; vertical swipes scroll the page. Previous/next buttons and arrow keys reach every project. Home and End select the first and last project. The active project link opens its archive notes and moves focus to the entry.
data-warp-ready appears once the images and renderer are ready. To control a reel after that event:
Code snippet omitted: it ships with the download.
Scroll and Archive Motion
The wordmark unfolds from its baseline, letter by letter, on arrival, then compresses, tilts and fades out as you scroll past the header. Reduced motion shows the settled letters immediately. The studio print shifts within its crop. Large project images start at 68% size on desktop (82% on mobile) and grow into place as they enter view, while their curved crops flatten and the photography gently zooms out. These are independent ScrollTriggers; remove the relevant data-wordmark, data-studio-photo or data-photo-window hook to leave that element static.
Archive previews follow the pointer and also appear on keyboard focus. Native summary controls open the full project notes with Enter or Space. Touch visitors use those same controls directly. The preview is supplementary; every preview image is also present in the entry itself.
Palette
Edit the semantic tokens at the top of assets/style.css: charcoal ground and surface, warm ink, secondary ink, peach accent and rule colour. Update each matching --*-rgb triple as well. The header records measured contrast pairs; measure new colours at their actual uses, including text over photographs.
Archivo is the display and body family. Replace the Google Fonts link and the two font tokens to change it. The large wordmark has its own responsive sizing; check both its width and the smaller project captions after changing the face or studio name. This design ships with one palette and no theme picker.
Photographs
Six optimised local WebP derivatives are included, about 752 KB in total. They are cropped, slightly desaturated and exposure-adjusted for this page. The manifest preserves the source information and treatment.
To replace them, either overwrite the matching files in assets/img/ and update the alt text, or edit assets/img-manifest.json. In the GSAP Vault repository, regenerate with:
Code snippet omitted: it ships with the download.
That regeneration command uses the repository's asset-building tool; buyers deploying the static folder do not need it. Wide photographs with a clear subject and strong outlines work well in the reel. Keep critical lettering and faces away from the outer edges. The flatter studies and archive entries let visitors inspect the work without distortion.
Credits
- Yellow pleated pendant lamps: https://images.pexels.com/photos/20152628/pexels-photo-20152628.jpeg?auto=compress&cs=tinysrgb&w=2400 — Pexels licence.
- Rusted orange sculptural curves against flat blue sky: https://images.unsplash.com/photo-1486718448742-163732cd1544?q=80&w=1920&auto=format&fit=crop — Unsplash licence.
- Aerial surf breaking on a dark shore: https://images.pexels.com/photos/5851472/pexels-photo-5851472.jpeg?auto=compress&cs=tinysrgb&w=2400 — Pexels licence.
- Yellow tracksuit on a sunlit basketball court: https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?q=80&w=1600&auto=format&fit=crop — Unsplash licence.
- Still life: board, vase and candle on stone: https://images.pexels.com/photos/7607461/pexels-photo-7607461.jpeg?auto=compress&cs=tinysrgb&w=2400 — Pexels licence.
- Angular glass museum against a bright sky: https://images.unsplash.com/photo-1487958449943-2429e8be8625?q=80&w=1600&auto=format&fit=crop — Unsplash licence.
Accessibility and Fallbacks
- Without JavaScript, reduced-motion preferences, or WebGL 2 support, the reel becomes a normal photographic list with every project and link available. The rest of the page remains in document flow.
- Reduced motion has both CSS and JavaScript support. The page does not require a scroll animation to expose content.
- Native links, buttons and disclosure summaries carry visible focus styles. The carousel announces project changes and keeps only the active project link in its tab order while enhanced.
- The WebGL source images are decoded before enhancement. A blocked dependency or failed image load restores the source list.
- No pointer-only action is required to read a project. Vertical touch gestures remain page scrolling even when they start on the reel.
Smooth Scrolling
Lenis is optional. Set data-smooth="off" on <html> or use ?smooth=off to use native scrolling. Reduced motion also disables smooth scrolling on initial load. Lenis and ScrollTrigger share GSAP’s clock. If removing Lenis, remove its CDN tag and the complete initLenis block; leave ScrollTrigger available for the other animations.
Dependencies and Performance
| Dependency | Role |
|---|---|
| GSAP 3.12+ (this build pins 3.15.0) | Responsive conditions, tweening, frame scheduling and teardown. |
| ScrollTrigger | The wordmark, studio photograph and project-study scroll treatments. |
| three.js r180 ES module | Rendering and shader deformation of the photo reel. |
| Lenis 1.3.17 | Optional smooth page scrolling. |
| Archivo | Optional Google Fonts typography. |
The animated reel needs WebGL 2, import maps and ES modules. Browsers without these enhancements retain the project content. There is one renderer, with resolution capped and rendering suspended when the reel is out of view or the document is hidden. Desktop uses two finite pins: the reel (2.6 viewport heights) and the photographic accordion (1.15 viewport heights). Phones and reduced-motion layouts stay unpinned. The thumbnail uses the same page styles and reel shaders with a frozen representative state; thumbnail.html is a preview asset and is excluded from the buyer download.
Photographic Accordion
The Another Dimension section separates one image into five strips and brings them together again. Desktop scrolling controls the pinned sequence; the slider can seek its opening half directly. On phones the slider and button animate the strips without pinning. Replace the photograph in both the section image and .perspective-slice background in the stylesheet. Without motion or JavaScript, the section shows the complete photograph.
Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.