201 lines
5.8 KiB
Markdown
201 lines
5.8 KiB
Markdown
# 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 and focused on high-quality image reveals.
|
|
|
|
## Architecture Overview
|
|
|
|
The animation system is split into two main parts:
|
|
|
|
1. **Animations Library** ([`gsap-animations.js`](../src/assets/scripts/bundle/gsap-animations.js))
|
|
- Reusable zoom presets: `punchIn`, `punchOut`
|
|
- Default variables with simple override merging
|
|
- `shouldAnimate()` utility respecting `prefers-reduced-motion`
|
|
|
|
2. **Content Animations** ([`gsap-shortcode-init.js`](../src/assets/scripts/bundle/gsap-shortcode-init.js))
|
|
- Scroll-triggered animations in markdown/blog posts
|
|
- Paired shortcode reads JSON config and passes it through. The shortcode also passes arguments for a Tailwind class name.
|
|
- We must remember that this is the only function of Tailwind that we use and that we should consult files in ([`our design tokens`](../src/assets/css/global/global.css)), and be mindful of the fact that these animations will exist as containers of ([`prose.css`](../src/assets/css/global/blocks/prose.css)).
|
|
|
|
---
|
|
|
|
# For Content Authors
|
|
|
|
See [GSAP_USAGE.md](./GSAP_USAGE.md) for shortcode usage.
|
|
|
|
## Quick Start
|
|
|
|
### Punch In Animation
|
|
|
|
```markdown
|
|
{% gsapScrollAnim { "animationType": "punchIn", "focalX": 75, "focalY": 25, "startZoom": 1, "endZoom": 2.5 } %}
|
|
[{ "src": "/images/detail-photo.jpg", "alt": "Macro photography showing fine detail" }]
|
|
{% endgsapScrollAnim %}
|
|
```
|
|
|
|
---
|
|
|
|
# For Developers
|
|
|
|
## Configuration Options
|
|
|
|
All parameters are optional with sensible defaults and fully passed through:
|
|
|
|
```javascript
|
|
{
|
|
"animationType": "punchIn", // punchIn or punchOut
|
|
"scrollStart": "top 80%", // Timeline start
|
|
"scrollEnd": "bottom 20%", // Timeline end
|
|
"scrub": true, // Tie progress to scroll
|
|
"containerClass": "gsap-container",
|
|
"spillingInto": false, // false | true | 'prose' | 'bleed'
|
|
"pin": true,
|
|
"markers": false,
|
|
// Punch-specific overrides
|
|
"focalX": 50, // 0-100 (% from left)
|
|
"focalY": 50, // 0-100 (% from top)
|
|
"startZoom": 1, // 1 for punchIn, 2.5 for punchOut
|
|
"endZoom": 2.5, // 2.5 for punchIn, 1 for punchOut
|
|
"ease": "power2.inOut"
|
|
}
|
|
```
|
|
|
|
## 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).
|
|
|
|
## Example
|
|
|
|
### 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
|
|
<div class="gsap-container" data-gsap-scroll-anim='{...}'>
|
|
<div class="gsap-item">
|
|
<figure class="gsap-image-wrapper">
|
|
<picture>
|
|
<img class="gsap-image" src="..." alt="...">
|
|
</picture>
|
|
<figcaption>...</figcaption>
|
|
</figure>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
Add custom styles in your CSS:
|
|
```css
|
|
.gsap-container.featured-image {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.gsap-item {
|
|
margin-bottom: 2rem;
|
|
}
|
|
```
|
|
|
|
## Accessibility
|
|
|
|
- Respects `prefers-reduced-motion` - animations disabled automatically
|
|
- All images require `alt` text
|
|
- ScrollTrigger callbacks maintain proper ARIA states
|
|
|
|
## Turbo Drive Compatibility
|
|
|
|
Animations are automatically cleaned up and re-initialized on Turbo navigation:
|
|
- Contexts reverted before page change
|
|
- ScrollTrigger instances killed
|
|
- Re-initialized after new page loads
|
|
|
|
## Debugging
|
|
|
|
Enable debug markers to visualize scroll trigger points:
|
|
|
|
```markdown
|
|
{% gsapScrollAnim {
|
|
"animationType": "fadeIn",
|
|
"markers": true
|
|
} %}
|
|
[...]
|
|
{% endgsapScrollAnim %}
|
|
```
|
|
|
|
This shows colored markers in viewport indicating trigger start/end positions.
|
|
|
|
## Performance
|
|
|
|
- Animations use GPU-accelerated properties (`transform`, `opacity`)
|
|
- `will-change` applied for optimization
|
|
- ScrollTrigger efficiently batches calculations
|
|
- Contexts properly cleaned up on navigation
|
|
|
|
## Files
|
|
|
|
- Library: `src/assets/scripts/bundle/gsap-animations.js`
|
|
- Shortcode initializer: `src/assets/scripts/bundle/gsap-shortcode-init.js`
|
|
- Shortcode: `src/_config/shortcodes/gsap.js`
|
|
- CSS: `src/assets/css/global/utilities/gsap-animations.css`
|