01 — Overview
Figma-to-React conversion featuring advanced GSAP animations. Deep dive into timeline orchestration, scroll-triggered animations, and performant motion design.
The Challenge
The client provided a Figma design for a personal portfolio featuring complex scroll-triggered animations, parallax effects, and orchestrated entrance sequences. The design required precise timing and smooth performance while maintaining a 60fps experience across devices.
The main challenge was translating static Figma frames into fluid, timeline-based animations using GSAP while integrating seamlessly with React's component lifecycle and avoiding common pitfalls like animation cleanup and memory leaks.
Implementation
I built the project using React and GSAP's Timeline API, which allowed me to sequence multiple animations with precise control over timing, easing, and overlap. The key was using the useGSAP hook from @gsap/react for proper React integration.
const HeroSection = () => {
const containerRef = useRef(null);
const titleRef = useRef(null);
const imageRef = useRef(null);
useGSAP(() => {
const tl = gsap.timeline({
scrollTrigger: {
trigger: titleRef.current,
start: 'top 80%',
}
});
// Orchestrated entrance
tl.from(titleRef.current, {
opacity: 0, y: 50, duration: 1
})
.from(imageRef.current, {
scale: 0.8, opacity: 0
}, '-=0.5'); // Overlap by 0.5s
}, { scope: containerRef });
return (...);
}Using useGSAP from @gsap/react instead of useEffect provides automatic cleanup and better React 19 compatibility. Timeline overlap ('-=0.5') creates smooth, overlapping animations that feel organic rather than robotic.
Animation Architecture
The project featured several animation patterns:
start: 'top 80%' for optimal timing.scrub: true for smooth, scroll-linked animation.'-=0.5'.gsap.to() with smooth easing curves like power3.out.Performance Optimization
Achieving 60fps animations required careful optimization:
transform and opacity properties instead of layout-triggering properties like top/left.will-change: transform to elements with complex animations.scope parameter in useGSAP to limit GSAP's query scope, improving performance.Results
The client was extremely satisfied with the smooth, professional animations that matched their design vision perfectly. The portfolio successfully showcased their work while maintaining excellent performance metrics.
Key Learnings
Timeline Mastery
GSAP Timeline's position parameter ('-=0.5', '+=0.2') is incredibly powerful for creating overlapping animations. This creates more natural, fluid sequences compared to sequential timing.
React Integration Done Right
Using useGSAP instead of useEffect eliminated cleanup issues and StrictMode double-render problems. The scope parameter is essential for preventing animation conflicts.
Performance-First Animation
Learned to prioritize transform and opacity over layout properties. Using Chrome DevTools Performance tab to profile animations revealed which properties cause repaints vs compositing-only changes.
ScrollTrigger Best Practices
The start and end parameters need careful tuning. Setting markers: true during development was invaluable for visualizing trigger points and debugging scroll-linked animations.
Technical Insights
Easing Curves Matter: GSAP's power3.out and power4.inOut create much more natural motion than linear easing. Custom easing with CustomEase plugin can match exact Figma animation curves.
Stagger is Powerful: The stagger property can accept functions for complex stagger patterns: stagger: { each: 0.1, from: "center" }
Context Safe: Always use gsap.context() or useGSAP scope to prevent animations from affecting elements outside the component.
Delay vs Position: Using timeline position parameters ('-=0.5') is better than individual delay properties for maintaining a single source of truth for animation timing.


