Skip to main content

GSAP Timeline Studio

Compose a scroll-tied GSAP timeline for the Custom Code (Motion Snippet) field — the things the built-in Scroll Motion effects can't do: choreograph several targets on one timeline, real 3D, full per-property control, keyframes, loops and advanced stagger. Build it below, watch it run, copy the code.

1
ypx
opacity
2
rotationYdeg
opacity
perspectivepx
Timeline & trigger

Trigger start & Scrub are options next to the code field in the builder. Loop is written into the snippet.

Preview
Your element
Card 1
Card 2
Card 3
1.0s
Paste into Motion Snippet (GSAP)
tl
  .from(el, { y: 60, opacity: 0, duration: 0.8, ease: 'power2.out' })
  .from(el.querySelectorAll('.card'), { rotationY: 60, opacity: 0, transformPerspective: 1000, duration: 0.8, ease: 'power2.out', stagger: 0.1 }, '<');
Also set next to the code field in the builder:
Trigger start → When 20% into view (default)Scrub → Play once on enter

One tl (already ScrollTrigger-tied), your el and its children — composed into a single scroll timeline. All GSAP core, so every snippet pastes and runs as-is.

How the Custom Code field works

Your snippet runs with three things already set up — you just add tweens to the timeline:

You getWhat it is
elThis element. Target its children with el.querySelectorAll('.card').
tlA gsap.timeline() already tied to a ScrollTrigger on el. Add tweens to it.
gsapThe GSAP object, if you need it directly.
Good to know
  • Admin-only by design. Baked snippets execute only when the page author can use unfiltered HTML (an admin), so untrusted code never runs.
  • Reduced motion & mobile are respected automatically — snippets skip for visitors who ask for reduced motion, and can be disabled on phones.
  • GSAP core + ScrollTrigger only. SplitText / MorphSVG / MotionPath and other plugins aren't guaranteed to be loaded for a snippet, so the Studio stays on core — which still covers everything here.
  • Trigger start & scrub are options next to the code field (the snippet is what animates; those control when). Loop is written into the snippet.

Why use this over the built-in effects?

The Scroll Motion tiles apply one effect to one target. Custom Code lets you do what they can't — and the Studio writes it for you:

  • Choreograph a composition — heading rises, then cards stagger in, then a button pops, all on one timeline.
  • Real 3DrotationX/Y + transformPerspective for card flips, door-opens, cube turns.
  • Keyframes — multi-stage motion (bounce, wobble, shake, glitch) impossible with a single preset.
  • Loopsrepeat / yoyo for float / pulse / breathe that never stops.
  • Advanced stagger — from center / edges / random, for grids and cascades.

Advanced recipes

Paste-ready snippets that are flatly impossible in the options UI (all core GSAP):

Heading, then a 3D-flip card stagger:

tl.from(el.querySelector('h2'), { y: 40, opacity: 0, duration: 0.7, ease: 'power3.out' })
.from(el.querySelectorAll('.card'), {
rotationY: 60, opacity: 0, transformPerspective: 1000,
stagger: { each: 0.1, from: 'start' }, duration: 0.7, ease: 'power2.out'
}, '-=0.3');

Letter cascade (wrap letters in <span class="ch"> in your Text Block):

tl.from(el.querySelectorAll('.ch'), { yPercent: 120, opacity: 0, stagger: 0.04, ease: 'power4.out', duration: 0.7 });

Grid-stagger reveal from the centre, with overshoot:

tl.from(el.querySelectorAll('.card'), {
scale: 0, opacity: 0, transformOrigin: 'center',
stagger: { grid: 'auto', from: 'center', amount: 0.6 }, ease: 'back.out(1.7)'
});

Ambient floating loop (never stops):

tl.to(el, { y: -12, duration: 1.6, ease: 'sine.inOut', repeat: -1, yoyo: true });

Bounce-in with keyframes:

tl.to(el, { keyframes: { y: [60, 0, -18, 0], opacity: [0, 1, 1, 1] }, duration: 1, ease: 'power1.out' });

Glitch (keyframed jitter):

tl.to(el, { keyframes: { x: [0, -6, 6, -4, 0], skewX: [0, 10, -8, 4, 0] }, duration: 0.5, ease: 'steps(5)' });

Where to learn more

The generated code is standard GSAP — the official GSAP docs cover every tween property, ease, the timeline position parameter, and advanced stagger if you want to go further.