Complex Animation Sequences
A complex animation sequence means multiple elements moving in a coordinated order — a logo appears, a headline slides in, features stagger up, an image scales in, a button arrives last. The whole thing feels choreographed. GSAP timelines make this precise and controllable.
The prompting approach
Don’t describe everything at once. Write a numbered list of what happens when — Claude Code reads it like a script and translates each step into a timeline tween.
Prompt:
"페이지 로드 시 다음 순서로 나타나는 GSAP timeline을 만들어줘.
paused: true로 시작하고 Play 버튼으로 실행되게 해줘.
1. .brand (로고) — scale 0.8→1, opacity 0→1, 0.5s
2. .headline span (두 줄 제목) — y 60→0, opacity 0→1, stagger 0.15s, 0.7s, -=0.2로 겹치기
3. .feature-item (4개 항목) — x -20→0, opacity 0→1, stagger 0.12s, -=0.3
4. .mockup (이미지 플레이스홀더) — scale 0.92→1, opacity 0→1, 0.6s, 3번과 동시에 시작
5. .cta 버튼 — y 16→0, opacity 0→1, 0.4s, -=0.2
ease는 모두 power2.out"
The position parameter
The second argument to tl.from() controls when a tween starts relative to the timeline:
| Position | Meaning |
|---|---|
'-=0.3' | Start 0.3s before the previous tween ends |
'+=0.1' | Start 0.1s after the previous tween ends |
'<' | Start at the same time as the previous tween |
'<0.3' | Start 0.3s after the previous tween started |
'myLabel' | Jump to a named label |
These overlapping positions are what make sequences feel fluid instead of choppy.
Controlling timelines
Once you have a timeline, you can wire up controls:
tl.play(); // Start from current position
tl.pause(); // Freeze in place
tl.reverse(); // Play backwards from current position
tl.restart(); // Jump to start and play forward
tl.seek(0.5); // Jump to 0.5s mark (does not play)
Ask Claude Code to add these controls with a simple prompt:
"Play / Pause / Reverse / Restart 버튼 4개를 추가하고
각각 tl.play(), tl.pause(), tl.reverse(), tl.restart()에 연결해줘."
Timeline progress bar
To show animation progress visually, use onUpdate:
const tl = gsap.timeline({
onUpdate: () => {
bar.style.width = (tl.progress() * 100) + '%';
}
});
What the demo shows
The demo is a product showcase landing page hero. A logo, headline, feature list, mockup image, and CTA button all appear through a coordinated GSAP timeline. Four control buttons let you play, pause, reverse, and restart the sequence. A thin progress bar below the controls tracks animation progress in real time.
복잡한 애니메이션 시퀀스는 gsap.timeline()으로 구성합니다. 타임라인은 여러 트윈을 순서대로 실행하고, 오프셋으로 겹치거나 지연시킬 수 있습니다.
입장 시퀀스
페이지 로드 시 입장 시퀀스:
1. 배경 fade in (0.4s)
2. 이미지 scale 0.8→1 + fade in (0.6s, 이전과 0.2s 겹침)
3. 제목 slide up (0.5s, 이전 완료 후)
4. 버튼들 stagger fade in (0.3s total, 제목과 동시)
gsap.timeline({ defaults: { ease: 'power2.out' } }) 사용.
타임라인에서 '<'는 이전 트윈과 동시에, '<0.2'는 0.2초 겹쳐서 시작을 의미합니다.
무한 루프
3개의 슬라이드를 무한 루프로 전환:
- 현재 슬라이드: opacity 1→0, translateX 0→-100%
- 다음 슬라이드: opacity 0→1, translateX 100%→0
gsap.timeline({ repeat: -1, yoyo: false }).
복잡한 시퀀스를 설명할 때는 항상 순서, 타이밍, 겹침을 명시하세요.
// ── Timeline setup ────────────────────────────────────────────
// paused: true → user controls playback via the buttons below
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
const hint = document.getElementById('hint');
const tl = gsap.timeline({
paused: true,
defaults: { ease: 'power2.out' },
onUpdate: () => {
const pct = Math.round(tl.progress() * 100);
progressFill.style.width = pct + '%';
progressText.textContent = pct + '%';
},
onStart: () => {
hint.classList.add('hidden');
},
});
// Step 1 — Brand mark scales in
tl.from('.brand', {
scale: 0.8,
opacity: 0,
duration: 0.5,
})
// Step 2 — Headline lines slide up with stagger, overlaps step 1 by 0.2s
.from('.headline span', {
y: 60,
opacity: 0,
stagger: 0.15,
duration: 0.7,
}, '-=0.2')
// Step 3 — Feature list items come in from the left, overlaps step 2 by 0.3s
.from('.feature-item', {
x: -20,
opacity: 0,
stagger: 0.12,
duration: 0.5,
}, '-=0.3')
// Step 4 — Mockup scales in, starts at the same time as step 3 + 0.3s offset
.from('.mockup', {
scale: 0.92,
opacity: 0,
duration: 0.6,
}, '<0.3')
// Step 5 — CTA slides up, overlaps step 4 by 0.2s
.from('.cta', {
y: 16,
opacity: 0,
duration: 0.4,
}, '-=0.2');
// ── Controls ──────────────────────────────────────────────────
document.getElementById('btnPlay').addEventListener('click', () => {
tl.play();
});
document.getElementById('btnPause').addEventListener('click', () => {
tl.pause();
});
document.getElementById('btnReverse').addEventListener('click', () => {
hint.classList.remove('hidden');
hint.textContent = 'Press Play to start the sequence';
tl.reverse();
});
document.getElementById('btnRestart').addEventListener('click', () => {
hint.classList.add('hidden');
tl.restart();
});
// ── Nav entrance (always plays) ───────────────────────────────
gsap.from('.site-nav', {
y: -16,
opacity: 0,
duration: 0.4,
ease: 'power3.out',
});