Learn how to create stunning, high-performance animations using GSAP, the industry-standard animation library for the web. 🚀
Getting Started 🎯
First, let's set up GSAP in your project.
# Using npm
npm install gsap
# Using yarn
yarn add gsap
Basic Animations 🎨
// Basic Tween
gsap.to(".box", {
duration: 1,
x: 100,
y: 50,
rotation: 360,
scale: 1.5,
ease: "power2.out"
});
// From Animation
gsap.from(".box", {
duration: 1,
opacity: 0,
y: 100,
stagger: 0.2
});
// FromTo Animation
gsap.fromTo(".box",
{
opacity: 0,
y: 100
},
{
duration: 1,
opacity: 1,
y: 0,
ease: "back.out(1.7)"
}
);
Timeline Animations ⏱️
// Creating a Timeline
const tl = gsap.timeline({
defaults: {
duration: 1,
ease: "power2.out"
}
});
tl.from(".header", { y: -100, opacity: 0 })
.from(".sidebar", { x: -100, opacity: 0 }, "-=0.5")
.from(".content", { y: 50, opacity: 0 }, "-=0.5")
.from(".footer", { y: 100, opacity: 0 }, "-=0.5");
// Timeline with Labels
const tl2 = gsap.timeline();
tl2.add("start")
.to(".box1", { x: 100 })
.add("middle")
.to(".box2", { y: 100 })
.add("end")
.to(".box3", { rotation: 360 });
// Play from Label
tl2.play("middle");
ScrollTrigger Integration 📜
// Basic ScrollTrigger
gsap.to(".parallax", {
scrollTrigger: {
trigger: ".parallax",
start: "top center",
end: "bottom center",
scrub: true,
markers: true // for development
},
y: 100,
opacity: 0.5
});
// Advanced ScrollTrigger
gsap.to(".section", {
scrollTrigger: {
trigger: ".section",
start: "top top",
end: "+=500",
pin: true,
pinSpacing: false,
scrub: 1,
toggleActions: "play reverse play reverse"
},
scale: 1.2,
rotation: 360
});
// Parallax Effect
gsap.utils.toArray(".parallax-section").forEach(section => {
const depth = section.dataset.depth || 1;
gsap.to(section, {
scrollTrigger: {
trigger: section,
start: "top bottom",
end: "bottom top",
scrub: true
},
y: (i, target) => {
return (target.offsetHeight * depth) * 0.5;
}
});
});
Complex Animations 🎭
// Staggered Animation
gsap.from(".grid-item", {
duration: 1,
scale: 0,
y: 60,
opacity: 0,
rotation: 45,
stagger: {
amount: 1.5,
grid: "auto",
from: "center"
},
ease: "power3.out"
});
// Morphing SVG
gsap.to("#path", {
duration: 2,
morphSVG: {
shape: "#target-path",
type: "rotational"
},
ease: "power2.inOut"
});
// Text Animation
const text = new SplitText(".heading", {
type: "chars,words,lines"
});
gsap.from(text.chars, {
duration: 1,
opacity: 0,
scale: 0,
y: 80,
rotationX: 180,
transformOrigin: "0% 50% -50",
stagger: 0.01,
ease: "back.out(1.7)"
});
Performance Optimization 🚀
// Use Transform Instead of Position
// Good
gsap.to(".element", {
x: 100, // transforms
y: 100,
rotation: 360
});
// Avoid
gsap.to(".element", {
left: 100, // triggers layout
top: 100
});
// Batch DOM Updates
gsap.to(".multiple-elements", {
duration: 1,
opacity: 0,
y: 100,
stagger: 0.1,
force3D: true, // hardware acceleration
will-change: "transform"
});
// Use requestAnimationFrame
let progress = 0;
let animating = false;
function animate() {
if (!animating) return;
progress += 0.01;
gsap.set(".element", {
x: Math.sin(progress) * 100
});
requestAnimationFrame(animate);
}
// Start/Stop Animation
function toggleAnimation() {
animating = !animating;
if (animating) animate();
}
Interactive Animations 🎮
// Draggable Elements
Draggable.create(".draggable", {
type: "x,y",
bounds: ".container",
inertia: true,
onDrag: function() {
console.log("dragging");
},
onDragEnd: function() {
console.log("drag ended");
}
});
// Mouse Follow Animation
const cursor = document.querySelector(".cursor");
window.addEventListener("mousemove", (e) => {
gsap.to(cursor, {
duration: 0.5,
x: e.clientX,
y: e.clientY,
ease: "power2.out"
});
});
// Interactive Menu
const menu = document.querySelector(".menu");
const items = menu.querySelectorAll(".menu-item");
items.forEach(item => {
item.addEventListener("mouseenter", () => {
gsap.to(item, {
duration: 0.3,
scale: 1.1,
color: "#ff0000",
ease: "power2.out"
});
});
item.addEventListener("mouseleave", () => {
gsap.to(item, {
duration: 0.3,
scale: 1,
color: "#000000",
ease: "power2.in"
});
});
});
React Integration ⚛️
// Using GSAP with React
import { useEffect, useRef } from 'react';
import gsap from 'gsap';
function AnimatedComponent() {
const elementRef = useRef(null);
useEffect(() => {
const element = elementRef.current;
const tl = gsap.timeline({
scrollTrigger: {
trigger: element,
start: "top center",
end: "bottom center",
scrub: 1
}
});
tl.from(element, {
duration: 1,
opacity: 0,
y: 100,
ease: "power2.out"
});
return () => {
tl.kill();
};
}, []);
return (
<div ref={elementRef} className="animated-element">
Content
</div>
);
}
// Custom Hook for GSAP
function useGSAP(callback, deps = []) {
useEffect(() => {
const ctx = gsap.context(callback);
return () => ctx.revert();
}, deps);
}
// Usage
function App() {
useGSAP(() => {
gsap.to(".box", {
rotation: 360,
duration: 2,
repeat: -1
});
});
return <div className="box">Rotating Box</div>;
}
Advanced Techniques 🔧
// Custom Easing
CustomEase.create("myEase", "M0,0 C0.25,0.1 0.25,1 1,1");
gsap.to(".element", {
duration: 1,
x: 100,
ease: "myEase"
});
// Physics-based Animation
gsap.to(".ball", {
duration: 2,
y: 500,
ease: "bounce.out"
});
// Morph SVG Paths
gsap.to("#path", {
duration: 2,
morphSVG: {
shape: "#target",
type: "rotational",
origin: "50% 50%"
}
});
// Custom Effects
gsap.registerEffect({
name: "fadeAndSlide",
effect: (targets, config) => {
return gsap.to(targets, {
duration: config.duration || 1,
opacity: 0,
y: 100,
stagger: config.stagger || 0.2
});
},
defaults: { duration: 1 }
});
// Use Custom Effect
gsap.effects.fadeAndSlide(".element", {
duration: 2
});
Best Practices 📝
- Use transforms instead of positions
- Implement proper cleanup
- Optimize performance
- Use timeline for complex animations
- Implement proper error handling
- Use proper event handling
- Implement proper testing
- Follow GSAP conventions
- Use proper documentation
- Optimize bundle size
Additional Resources
GSAP provides powerful tools for creating high-performance animations on the web. Its robust feature set and excellent browser support make it an excellent choice for creating engaging user experiences.