4.2 KiB
GSAP Animation System (Punch animations)
This project uses GSAP for scroll-driven punch animations (zoom in/out effects) via shortcodes. The system is intentionally minimal.
Architecture
1. Animations Library (gsap-animations.js)
Contains reusable zoom presets and shouldAnimate().
2. Content Animations (gsap-shortcode-init.js)
Handles scroll-triggered animations in markdown/blog posts via shortcodes.
3. UI Component Animations (mix-nav-animations.js)
Handles interactive animations for navigation, buttons, and UI elements.
For Content Authors (Markdown/Posts)
Basic Usage
Punch into a focal point on scroll:
{% gsapScrollAnim {
"animationType": "punchIn",
"focalX": 50,
"focalY": 50,
"startZoom": 1,
"endZoom": 2.5
} %}
[{ "src": "/path/to/high-res-image.jpg", "alt": "Image to punch into" }]
{% endgsapScrollAnim %}
Available Animation Types
punchIn- Punch into image focal point (zoom in)punchOut- Punch out from focal point (zoom out)
Punch Animations with Focal Points
{% gsapScrollAnim {
"animationType": "punchIn",
"focalX": 30,
"focalY": 40,
"startZoom": 1,
"endZoom": 2.5,
"scrub": true
} %}
[{
"src": "/path/to/high-res-image.jpg",
"alt": "Image to zoom"
}]
{% endgsapScrollAnim %}
focalX/focalY: 0-100 (percentage of image dimensions)startZoom/endZoom: Scale values (1 = normal size)
Scroll Control Options
scrub (default: true)
true- Animation tied to scroll position (smooth)false- Animation plays once when triggered
scrollStart (default: "top 80%")
When animation begins:
"top 80%"- When element's top hits 80% down viewport"center center"- When element center hits viewport center"bottom 20%"- When element bottom hits 20% down viewport
scrollEnd (default: "bottom 20%")
When animation completes (for scrubbed animations)
pin (default: false)
Pin the element in place during animation:
{% gsapScrollAnim {
"animationType": "zoomIn",
"pin": true,
"scrollEnd": "+=500"
} %}
spillingInto (default: false)
Control layout overflow beyond prose margins:
false- Default: constrained within prose marginstrue/"prose"- Override margins for responsive bleed"bleed"- Full-width edge-to-edge breakout
{% gsapScrollAnim {
"animationType": "punchIn",
"spillingInto": "bleed"
} %}
[{ "src": "/path/to/image.jpg", "alt": "Full-width image" }]
{% endgsapScrollAnim %}
markers (default: false)
Show debug markers (for development).
Multiple Images
You can include multiple images; zoom applies to .gsap-image elements inside the container.
Tips
- Scrub for slow reveals - Set
"scrub": truefor scroll-controlled drama - No scrub for punchy moments - Set
"scrub": falsefor quick actions - Pin for focus - Use
"pin": trueto hold attention on an element - Zoom needs high-res - Zoom animations automatically request larger image sizes
For Developers
Library API
Zoom-only presets live in gsap-animations.js. Defaults are merged and can be overridden via shortcode config.
UI Component Animations
Create component-specific files like mix-nav-animations.js:
import gsap from 'gsap';
import { shouldAnimate } from './gsap-animations.js';
function initMyComponentAnimations() {
if (!shouldAnimate()) return;
document.querySelectorAll('.my-element').forEach(el => {
el.addEventListener('mouseenter', () => {
gsap.to(el, { scale: 1.1, duration: 0.2 });
});
});
}
// Turbo-compatible initialization
document.addEventListener('DOMContentLoaded', initMyComponentAnimations);
if (window.Turbo) {
document.addEventListener('turbo:load', initMyComponentAnimations);
}
Accessibility
All animations respect prefers-reduced-motion. Users with this preference will see static content without animations.
Debugging
Enable markers to see scroll trigger points via the shortcode config.
Check browser console for warnings about missing animation types or configuration errors.