# GSAP Animation System This project uses GSAP (GreenSock Animation Platform) for scroll-driven and interactive animations, designed for animated storytelling with low friction. ## Architecture Overview The animation system is split into three main parts: 1. **Shared Effects Library** ([`gsap-effects.js`](../src/assets/scripts/bundle/gsap-effects.js)) - Reusable animation effects (fadeIn, shake, zoom, etc.) - Emotional presets (jumpscare, anticipation, dread, etc.) - Effect composition utilities 2. **Content Animations** ([`gsap-shortcode-init.js`](../src/assets/scripts/bundle/gsap-shortcode-init.js)) - Scroll-triggered animations in markdown/blog posts - Low-friction shortcode syntax for content authors 3. **UI Component Animations** ([`mix-nav-animations.js`](../src/assets/scripts/bundle/mix-nav-animations.js)) - Interactive UI animations (hover, click, etc.) - Component-specific animation logic --- # For Content Authors See [GSAP_USAGE.md](./GSAP_USAGE.md) for the complete usage guide. ## Quick Start ### Emotional Presets (Recommended) Animate emotions, not numbers: ```markdown {% gsapScrollAnim { "emotion": "jumpscare" } %} [{ "src": "/scary-image.jpg", "alt": "Boo!" }] {% endgsapScrollAnim %} ``` Available emotions: `jumpscare`, `anticipation`, `dread`, `relief`, `tension`, `excitement` ### Simple Animations ```markdown {% gsapScrollAnim { "animationType": "fadeIn" } %} [{ "src": "/image.jpg", "alt": "Description" }] {% endgsapScrollAnim %} ``` ### Effect Composition Combine multiple effects: ```markdown {% gsapScrollAnim { "effects": ["fadeIn", "shake", "tremble"] } %} [{ "src": "/image.jpg", "alt": "Custom combo" }] {% endgsapScrollAnim %} ``` --- # For Developers ## Configuration Options All parameters are optional with sensible defaults: ```javascript { "animationType": "fadeIn", // Animation preset (see below) "scrollStart": "top 80%", // When animation starts "scrollEnd": "bottom 20%", // When animation completes "scrub": true, // Tied to scroll position (bidirectional) "containerClass": "gsap-container", // CSS class for wrapper "pin": false, // Pin element during animation "markers": false // Show debug markers (dev only) } ``` ### Animation Presets - **fadeIn** - Fade in from below (opacity + translate Y) - **fadeInUp** - Fade in from further below - **fadeInDown** - Fade in from above - **scaleIn** - Scale up with fade in (with bounce effect) - **slideInLeft** - Slide in from left side - **slideInRight** - Slide in from right side - **parallax** - Subtle vertical parallax effect - **stagger** - Sequential animation for multiple items - **zoomIn** - Start with full image, zoom into focal point - **zoomOut** - Start zoomed into focal point, pull back to full image ## Image Format Images are defined as JSON array inside the paired shortcode: ```json [{ "src": "/path/to/image.jpg", "alt": "Required alt text", "caption": "Optional caption text" }, { "src": "/path/to/image2.jpg", "alt": "Second image", "caption": "Another caption" }] ``` Images are automatically optimized via Eleventy Image plugin (WebP/JPEG, responsive sizes). ## Examples ### Single Image with Fade In ```markdown {% gsapScrollAnim { "animationType": "fadeIn" } %} [{ "src": "/images/photo.jpg", "alt": "Description" }] {% endgsapScrollAnim %} ``` ### Multiple Images with Stagger ```markdown {% gsapScrollAnim { "animationType": "stagger", "scrollStart": "top 70%" } %} [{ "src": "/images/photo1.jpg", "alt": "First photo", "caption": "Photo 1" }, { "src": "/images/photo2.jpg", "alt": "Second photo", "caption": "Photo 2" }] {% endgsapScrollAnim %} ``` ### Parallax Effect ```markdown {% gsapScrollAnim { "animationType": "parallax", "scrub": true } %} [{ "src": "/images/background.jpg", "alt": "Background scene" }] {% endgsapScrollAnim %} ``` ### Custom Container Class ```markdown {% gsapScrollAnim { "animationType": "scaleIn", "containerClass": "gsap-container featured-image" } %} [{ "src": "/images/hero.jpg", "alt": "Hero image" }] {% endgsapScrollAnim %} ``` ### Zoom In to Focal Point Draw attention to a specific detail in a high-resolution photograph: ```markdown {% gsapScrollAnim { "animationType": "zoomIn", "focalX": 75, "focalY": 25, "startZoom": 1, "endZoom": 2.5 } %} [{ "src": "/images/detail-photo.jpg", "alt": "Macro photography showing fine detail" }] {% endgsapScrollAnim %} ``` **Zoom Parameters:** - `focalX` (0-100): Horizontal focal point percentage from left (default: 50) - `focalY` (0-100): Vertical focal point percentage from top (default: 50) - `startZoom`: Initial scale (default: 1 = 100%) - `endZoom`: Final scale (default: 2.5 = 250%) **zoomIn**: Starts with full image visible, zooms into the focal point **zoomOut**: Starts zoomed into focal point, pulls back to show full image High-resolution images (up to 3200px) are automatically loaded for zoom animations to preserve detail when scaled. ## ScrollTrigger Settings ### scrollStart / scrollEnd Control when the animation begins and ends relative to viewport: - `"top bottom"` - Element's top enters viewport bottom - `"top 80%"` - Element's top at 80% viewport height - `"center center"` - Element center aligns with viewport center - `"bottom top"` - Element bottom exits viewport top Default: `scrollStart: "top 80%"`, `scrollEnd: "bottom 20%"` ### scrub When `true` (default), animation progress is tied directly to scroll position, enabling bidirectional playback. When `false`, animation plays once when scroll position crosses `scrollStart` threshold. ## CSS Customization Default wrapper class: `.gsap-container` Generated structure: ```html