A collection of @wix/interact animation examples (~130 standalone HTML files) organized across multiple directories, plus an Animation Explorer (explorer.html) that lets you preview each animation in an iframe and control it with customization sliders.
interact-examples/
├── explorer.html ← The explorer UI (single self-contained HTML file, ~2600 lines)
├── full-lean.md ← @wix/interact API documentation reference
├── AGENTS.md ← This file
├── CLAUDE.md ← Claude Code guidance
├── Gallery-and-Carousel/ ← 41 gallery/carousel/layout animations
├── Typographic_interactions/ ← 32 typographic/text animations
├── Image_Background/ ← 19 image/background effect animations
├── Lists/ ← 8 list/repeater animations
├── text_Image/ ← 5 HTML files + 3 subdirectories (text + image combos)
├── UI-elements-reyan/ ← 10 UI element animations (Reyan's implementations)
├── interact-UI-elements/ ← 10 UI element animations (interact implementations)
├── interact-WIP/ ← 2 work-in-progress animations
├── Animations not Interact/ ← 1 non-interact animation (for reference)
├── analysis/ ← Slider analysis CSVs, taxonomies, matrices, build scripts
└── explorer-screenshots/ ← Screenshots of the explorer UI
The explorer currently contains 63 animations across 3 directories:
- Gallery-and-Carousel: 37 of 41 on disk (missing: 3DSmallCarousel, CardSpread_7, Looping_Sphere_Gallery, SpecimenCardGallery)
- text_Image: 3 of 8 on disk (missing: pointer-scale-scroll-blur, pointer-track-scroll-fade, shape-mask-parallax, scroll-blur-split-layout, scroll-tilt-reveal)
- Typographic_interactions: 23 of 32 on disk (missing: 3D-Rolodex-Flip, Accelerated3DSpin, Mindshift Transition, The Iris Gate, Waterfall_Text, cards-peel-off-scroll, stacked-text-cards-scroll, text-cards-slide-in, text-fade-3d-perspective)
Not yet in explorer: Image_Background (19), Lists (8), UI-elements-reyan (10), interact-UI-elements (10), interact-WIP (2).
We are manually going through each animation one by one in explorer.html to:
- Test and tweak the existing sliders
- Add new sliders that are useful for each specific animation
- Remove sliders that don't work or aren't meaningful
- Adjust slider ranges (min/max/step/default) to sensible values
- Add new animations from disk that are not yet in the explorer
All slider configurations are hardcoded in the animations array inside explorer.html. They are NOT loaded from the CSV at runtime.
After all animations are finalized, the CSV files in analysis/ will be updated to match the final state of explorer.html.
The explorer is a single-file SPA (~2600 lines) with:
- Sidebar: Collapsible list of all animations, grouped by directory, with search
- Preview iframe: Full-bleed preview loading animations via
fetch→ HTML modification →srcdoc - Slider panel: Draggable glass-morphism panel with two tabs (Animation / Layout) with range sliders per animation
- Keyboard nav: Arrow keys to switch animations, Cmd+B to toggle sidebar
- The animation HTML is fetched via
fetch()and cached incachedHtml - A
<base href>tag is injected so relative URLs (images, CDN scripts) resolve correctly - A bridge script (
BRIDGE_SCRIPT) is injected before</body>— it:- Monkey-patches
Element.prototype.animateto track all Web Animations - Listens for
postMessagecommands from the parent explorer - Handles:
setSpeed,setCss,setCssVar,setScrollSpeed,reset
- Monkey-patches
- The modified HTML is loaded via
iframe.srcdoc(same-origin, enabling postMessage)
Each slider in the animations array has a type:
| Type | What it does | When it applies |
|---|---|---|
speed |
For non-scroll animations: sends setSpeed to bridge, which calls updatePlaybackRate() on all tracked Web Animations. For scroll-driven animations (viewProgress trigger): reloads the iframe with height-scaled HTML so the scroll range changes while the animation stays 0–100%. |
applySlider auto-detects based on triggers array |
css |
Injects a CSS rule with !important via the bridge's setCss handler |
Any animation |
cssVar |
Sets a CSS custom property on :root via the bridge's setCssVar handler |
Animations using CSS variables |
Scroll-driven animations use viewProgress as their trigger. The "Scroll Speed" slider works differently from regular speed:
- How scroll-driven animations work conceptually: Each scroll animation has a tall scroll section (e.g. 400vh) containing a
position: stickyinner container (100vh) that stays pinned in the viewport. The animation progresses from 0% → 100% as the user scrolls through the full length of that tall section. Scroll speed is really section length — a longer section means more scrolling to complete the animation (slower), a shorter section means less scrolling (faster). The "Scroll Speed" slider controls this by scaling the section height: speed 2× → half the height → animation completes in half the scroll distance → feels faster. Speed 0.5× → double the height → twice as much scrolling needed → feels slower. - It modifies the HTML source before loading, not after — this is critical because
@wix/interactcomputes itsViewTimelinescroll ranges at initialization time scaleScrollHeights(html, speed)uses regex to find and scale height values:- CSS
height: Nvhwhere N > 200 → scaled by1/speed - CSS
height: Npxwhere N > 2000 → scaled by1/speed - Tailwind
h-[Nvh]where N > 200 → scaled by1/speed - Tailwind
h-[Npx]where N > 2000 → scaled by1/speed
- CSS
- The slider uses
changeevent (mouse release) instead of continuousinput, since it requires an iframe reload currentScrollSpeedstate persists across reloads; resets to 1 when switching animations- The label dynamically shows "Scroll Speed" instead of "Animation Speed"
{
dir: 'Gallery-and-Carousel', // directory name
file: 'CardSpread.html', // filename
name: 'Card Spread', // display name
desc: 'Scroll-driven card spread…', // short description
triggers: ['viewProgress'], // interact trigger types
animText: '…', // raw animation parameter notes
layoutText: '…', // raw layout parameter notes
sliders: {
animation: [
{ label:'Animation Speed', type:'speed', min:0.1, max:3, step:0.1, val:1, unit:'×' },
// more sliders…
],
layout: [
{ label:'Card Border Radius', type:'css', sel:'.card', prop:'borderRadius', min:0, max:40, step:1, val:16, unit:'px' },
// more sliders…
]
}
}| Trigger | Description | Speed behavior |
|---|---|---|
viewProgress |
Scroll-driven (ViewTimeline) | Scroll height scaling (iframe reload) |
viewEnter |
Fires once when element enters viewport | updatePlaybackRate |
hover |
Mouse enter/leave | updatePlaybackRate |
pointerMove |
Continuous mouse tracking | updatePlaybackRate |
click |
Click interaction | updatePlaybackRate |
pageVisible |
Fires on page load | updatePlaybackRate |
customEffect |
JS-driven custom logic | updatePlaybackRate |
toggleEffect |
Toggle state | updatePlaybackRate |
- All changes go in
explorer.html— theanimationsarray is the single source of truth during this phase - Do NOT edit
animation_sliders.csvuntil all animations are finalized - Do NOT change the explorer infrastructure (bridge, sidebar, loading logic) unless something is broken
- When adding a slider, pick the right
type(css,cssVar, orspeed) and provide sensiblemin/max/step/valdefaults - For
csstype sliders, theselmust match elements inside the animation's HTML, andpropis the camelCase JS property name (converted to kebab-case automatically) - Test that slider ranges produce visible but non-breaking changes
- The
valshould be the animation's actual default value
The analysis/ folder contains prior slider analysis work:
animation_sliders.csv/animation_sliders_readable.csv/new_animation_sliders.csv— CSV catalogs of animations + sliders (snapshots, not yet synced with current explorer state)animation_taxonomies.csv/animation_taxonomies.md— Pattern categorization of animationsconclusions.md— Analysis findings (14 pattern categories, slider coverage insights)slider_analysis.md— Detailed slider audit notesslider_animation_matrixfiles — Cross-reference matrices (CSV + XLSX)build_matrix.py— Script to generate the matrix
Do NOT edit these files until the explorer slider audit is complete.
- Audit existing 63 explorer animations — go through each one, test sliders, fix ranges, add/remove as needed
- Add missing animations from existing directories to the explorer (18 files in Gallery-and-Carousel, text_Image, Typographic_interactions not yet included)
- Add new directories to the explorer — Image_Background (19), Lists (8), and potentially UI-elements-reyan / interact-UI-elements
- Update analysis CSVs to reflect the final slider configurations
For each animation:
- Visually inspect the animation
- Test existing sliders — do they work? Are ranges sensible?
- Add useful sliders that are missing
- Remove sliders that don't produce meaningful results
- Note any animations that need special handling (e.g., CornerFoldScroll and textFoldTransition use multiple 100vh sections that aren't caught by the > 200vh scroll speed threshold)
The explorer requires a local web server (for fetch to work):
cd interact-examples
npx serve .
# or
python3 -m http.serverThen open http://localhost:3000/explorer.html (or whatever port).
- Scroll speed threshold: Only heights > 200vh / > 2000px are scaled. Animations using multiple 100vh sections (CornerFoldScroll, textFoldTransition) won't scale with the scroll speed slider without custom handling.
- Some text_Image files use JSX/React (e.g.,
extrude_Swivel) and won't render in a vanilla iframe. - The bridge's
setSpeed(playbackRate) compresses scroll-driven animation ranges instead of extending them — that's why scroll-driven animations use the HTML-source-scaling approach instead. - CSS slider overrides use
!importantwhich can conflict with existing!importantrules in the animation source. - UI element animations (UI-elements-reyan, interact-UI-elements) are a different category from the gallery/typographic animations — they demonstrate form controls, toggles, dropdowns, etc. and may need different slider patterns.