← Back to Pixel
AgentPixel
Scoped Cleanup & Responsive Accessibility (
GSAP timeline animation
Coordinates multi-element animation with reusable timelines, predictable interruption and component-scoped cleanup.
gsap-timeline-animation
See how it helpsWhen is it useful?
Use when existing GSAP work needs choreography or reversible interactions beyond simple CSS transitions.
What does it help you do?
- Uses timeline positions instead of fragile chains of separate delays.
- Prevents repeated triggers from trapping elements in intermediate states.
- Scopes animation ownership and adapts to responsive or reduced-motion settings.
Try asking this
Animate our expandable panel with a reversible timeline that survives rapid clicks, resize and component removal. Reverse the panel halfway through opening, then enable reduced motion. It should reach the requested endpoint without stacking timelines or leaving invisible interactive content.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
GSAP & Timeline Animation
Use GSAP when a project already includes it or when a multi-element choreographed sequence, reversible timeline, or scrubbed scroll scene exceeds what CSS and basic WAAPI handle cleanly.
Core Timeline & Property Discipline
- Prefer transform shorthands and
autoAlpha:- Animate
x,y,xPercent,yPercent,scale,rotation, andautoAlpha(opacity+ automaticvisibility: hiddenwhen opacity reaches0so invisible elements never block clicks). - Register plugins (
ScrollTrigger,Flip,useGSAP) once at module initialization withgsap.registerPlugin(...).
- Animate
- Timelines over fragile
delaychains:- Coordinate multi-step sequences with
gsap.timeline({ defaults: { duration: 0.5, ease: 'power2.out' } })and position parameters ("<",">","-=0.15","<0.08", or named.addLabel('reveal')). Changing step 1's duration then shifts all downstream steps automatically.
- Coordinate multi-step sequences with
- Avoid
.from()flash of unstyled content (FOUC) & re-trigger traps:- Calling
gsap.from(el, { opacity: 0, y: 24 })repeatedly on rapid user clicks captures the current mid-tween value as the destination state, leaving elements stuck semi-transparent! - For re-triggerable interactions, use
.fromTo(el, { autoAlpha: 0, y: 24 }, { autoAlpha: 1, y: 0, overwrite: 'auto' })or control a persistent timeline instance (tl.play()/tl.reverse()).
- Calling
Scoped Cleanup & Responsive Accessibility (gsap.context & gsap.matchMedia)
Never leave loose global selector tweens (gsap.to('.card', ...)) that leak across component unmounts or affect unrelated DOM instances:
// Scope selectors to the component container and handle responsive + reduced-motion rules cleanly
const mm = gsap.matchMedia(containerEl);
mm.add(
{
isDesktop: '(min-width: 768px)',
isMobile: '(max-width: 767px)',
reduceMotion: '(prefers-reduced-motion: reduce)',
},
(context) => {
const { isDesktop, reduceMotion } = context.conditions!;
if (reduceMotion) {
gsap.set('.stage-card', { autoAlpha: 1, y: 0, clearProps: 'transform' });
return;
}
const tl = gsap.timeline({
scrollTrigger: {
trigger: containerEl,
start: 'top 75%',
end: 'bottom 25%',
toggleActions: 'play none none reverse',
},
});
tl.from('.stage-card', {
y: isDesktop ? 32 : 16,
autoAlpha: 0,
stagger: 0.08,
duration: 0.55,
ease: 'power3.out',
});
},
);
// On component unmount / teardown:
mm.revert(); // Reverts all tweens, inline styles, and ScrollTriggers created inside!
ScrollTrigger Guardrails
- Never attach
scrollTriggerto a child tween inside a timeline: A tween cannot be controlled by both a parent timeline's playhead and the scrollbar simultaneously. AttachscrollTriggerto the top-levelgsap.timeline({ scrollTrigger: { ... } }). - Refresh after layout shifts: Call
ScrollTrigger.refresh()after async data loads, accordion expansions, image decodes, or webfont readiness so cached start/end scroll offsets stay accurate.
Included files 1
SKILL.md
