GSAP's advanced plugins provide specialized functionality for physics simulations, custom easing, development tools, and unique animation effects that extend the core animation system.
import {
InertiaPlugin,
Physics2DPlugin,
CustomEase,
GSDevTools,
Flip,
Observer
} from "gsap/all";
gsap.registerPlugin(InertiaPlugin, Physics2DPlugin, CustomEase, GSDevTools, Flip, Observer);Create momentum-based animations with velocity, friction, and bounds.
interface InertiaVars {
inertia?: {
[property: string]: {
velocity?: number | "auto"; // Initial velocity
min?: number; // Minimum value
max?: number; // Maximum value
bounce?: number; // Bounce strength (0-1)
friction?: number; // Friction/resistance
unitFactors?: object; // Unit conversion factors
resistance?: number; // Resistance (deprecated, use friction)
};
};
}Usage Examples:
// Basic momentum animation
gsap.to(".ball", {
duration: 2,
inertia: {
x: { velocity: 500, friction: 0.9, min: 0, max: 400 },
y: { velocity: -300, friction: 0.8, bounce: 0.5 }
}
});
// Auto-detect velocity from user interaction
let startX, startY;
element.addEventListener("pointerdown", (e) => {
startX = e.clientX;
startY = e.clientY;
});
element.addEventListener("pointerup", (e) => {
gsap.to(".element", {
duration: 3,
inertia: {
x: { velocity: "auto", friction: 0.95, min: 0, max: 500 },
y: { velocity: "auto", friction: 0.9 }
}
});
});2D physics simulation with gravity, velocity, and acceleration.
interface Physics2DVars {
physics2D?: {
velocity?: number; // Initial velocity
angle?: number; // Launch angle in degrees
gravity?: number; // Gravity strength
friction?: number; // Air resistance
acceleration?: number; // Acceleration
accelerationAngle?: number; // Acceleration direction
};
}Usage Examples:
// Projectile motion
gsap.to(".projectile", {
duration: 3,
physics2D: {
velocity: 300, // Launch speed
angle: 45, // 45-degree angle
gravity: 500 // Gravity pulls down
}
});
// Multiple projectiles
gsap.to(".particle", {
duration: 4,
physics2D: {
velocity: () => gsap.utils.random(200, 400),
angle: () => gsap.utils.random(-30, 30),
gravity: 600,
friction: 0.1
},
stagger: 0.1
});Create custom easing curves using visual editor or mathematical functions.
/**
* Create custom easing function from path data
* @param id - Unique identifier for the ease
* @param path - SVG path data or Cubic Bezier values
* @param rawPath - Optional raw path data
* @returns Custom easing function
*/
CustomEase.create(id: string, path: string, rawPath?: any): EaseFunction;
/**
* Get easing function by ID
* @param id - Ease identifier
* @returns Easing function or null
*/
CustomEase.get(id: string): EaseFunction | null;Usage Examples:
// Create custom ease from Cubic Bezier
CustomEase.create("myEase", "M0,0 C0.25,0.46 0.45,0.94 1,1");
// Use custom ease
gsap.to(".element", {
duration: 2,
x: 100,
ease: "myEase"
});
// Create from Cubic Bezier values
CustomEase.create("bounceOut", "0.68, -0.55, 0.265, 1.55");
// Complex multi-point curve
CustomEase.create("wiggle", "M0,0 C0,0 0.056,0.442 0.175,0.442 0.294,0.442 0.332,0 0.332,0 0.332,0 0.414,1 0.671,1 0.991,1 1,0 1,0");First-Last-Invert-Play technique for seamless layout animations.
/**
* Capture current state of elements
* @param targets - Elements to capture state for
* @param props - Properties to capture
* @returns State object
*/
Flip.getState(targets: string | Element | Element[], props?: string | object): FlipState;
/**
* Animate from captured state to current state
* @param state - Previously captured state
* @param vars - Animation configuration
* @returns Timeline of flip animations
*/
Flip.from(state: FlipState, vars?: Flip.Vars): gsap.core.Timeline;
/**
* Animate to a captured state
* @param state - Target state to animate to
* @param vars - Animation configuration
* @returns Timeline of flip animations
*/
Flip.to(state: FlipState, vars?: Flip.Vars): gsap.core.Timeline;
/**
* Fit one element to another's bounds
* @param fromElement - Source element
* @param toElement - Target element bounds
* @param vars - Animation configuration
* @returns Tween animation
*/
Flip.fit(fromElement: Element, toElement: Element, vars?: Flip.Vars): gsap.core.Tween;Usage Examples:
// Basic FLIP animation
const state = Flip.getState(".cards");
// Make DOM changes (add/remove/reorder elements)
container.appendChild(card); // Move card to end
// Animate from old positions to new positions
Flip.from(state, {
duration: 0.8,
ease: "power2.inOut",
stagger: 0.1
});
// Responsive layout changes
const mediaQuery = gsap.matchMedia();
mediaQuery.add("(max-width: 768px)", () => {
const state = Flip.getState(".layout-items");
// Change to mobile layout
items.forEach(item => mobileContainer.appendChild(item));
Flip.from(state, {
duration: 0.6,
ease: "power2.out"
});
});
// Element morphing
const startState = Flip.getState(".morph-element");
element.classList.add("expanded");
Flip.from(startState, { duration: 1 });Unified scroll, touch, and pointer event handling with normalization.
/**
* Create Observer instance for unified event handling
* @param vars - Observer configuration
* @returns Observer instance
*/
Observer.create(vars: Observer.Vars): Observer;
interface Observer.Vars {
target?: Element | Window; // Element to observe
type?: string; // Event types: "scroll,touch,pointer"
// Scroll events
onChangeY?: Function; // Vertical scroll change
onChangeX?: Function; // Horizontal scroll change
// Touch/pointer events
onPress?: Function; // Press start
onRelease?: Function; // Press end
onMove?: Function; // Move during press
// Configuration
tolerance?: number; // Movement tolerance
preventDefault?: boolean; // Prevent default behaviors
wheelSpeed?: number; // Mouse wheel sensitivity
// Callbacks
onToggleX?: Function; // X direction toggle
onToggleY?: Function; // Y direction toggle
onStop?: Function; // Movement stops
}Usage Examples:
// Unified scroll handling
Observer.create({
target: window,
type: "scroll,touch,pointer",
onChangeY: (self) => {
gsap.to(".parallax", {
y: -self.velocityY * 0.3,
duration: 0.8
});
},
tolerance: 10,
preventDefault: true
});
// Touch gesture detection
Observer.create({
target: ".gesture-area",
type: "touch,pointer",
onMove: (self) => {
if (self.deltaX > 50) {
// Swipe right detected
triggerSwipeRight();
}
},
tolerance: 20
});Visual timeline controls and debugging tools for development.
/**
* Create visual dev tools for debugging animations
* @param vars - DevTools configuration
* @returns GSDevTools instance
*/
GSDevTools.create(vars?: GSDevTools.Vars): GSDevTools;
interface GSDevTools.Vars {
animation?: gsap.core.Animation; // Animation to control
globalSync?: boolean; // Sync with global timeline
paused?: boolean; // Start paused
id?: string; // Unique ID
minimal?: boolean; // Minimal UI
css?: string; // Custom CSS
container?: Element; // Container element
}
/**
* Kill all GSDevTools instances
*/
GSDevTools.killAll(): void;Usage Examples:
// Create dev tools for specific animation
const tl = gsap.timeline();
tl.to(".box", { x: 100, duration: 1 })
.to(".box", { y: 100, duration: 1 })
.to(".box", { rotation: 360, duration: 1 });
GSDevTools.create({
animation: tl,
paused: true
});
// Global timeline controls
GSDevTools.create({
globalSync: true,
minimal: true
});
// Custom positioned dev tools
GSDevTools.create({
container: document.querySelector(".dev-controls"),
css: `
.gs-dev-tools {
position: fixed;
top: 10px;
right: 10px;
}
`
});Combining multiple advanced plugins for complex effects.
// Physics with bounds checking using Flip
const physicsElements = gsap.utils.toArray(".physics-element");
physicsElements.forEach(element => {
// Capture initial state
const state = Flip.getState(element);
// Apply physics
gsap.to(element, {
duration: 3,
physics2D: {
velocity: gsap.utils.random(200, 400),
angle: gsap.utils.random(0, 360),
gravity: 300
},
onUpdate: function() {
// Check bounds and use Flip for corrections
const bounds = element.getBoundingClientRect();
if (bounds.bottom > window.innerHeight) {
const correctionState = Flip.getState(element);
gsap.set(element, { y: window.innerHeight - bounds.height });
Flip.from(correctionState, { duration: 0.1 });
}
}
});
});
// Custom ease with momentum
CustomEase.create("momentumEase", "0.25, 0.46, 0.45, 0.94");
gsap.to(".momentum-element", {
duration: 2,
x: 300,
ease: "momentumEase",
onComplete: function() {
// Apply inertia after initial animation
gsap.to(this.target, {
duration: 3,
inertia: {
x: { velocity: 100, friction: 0.9 }
}
});
}
});
// Observer with dev tools for debugging
const observer = Observer.create({
type: "scroll,touch",
onChangeY: (self) => {
const progress = Math.abs(self.velocityY) / 1000;
gsap.to(".reactive-element", {
scale: 1 + progress,
rotation: self.velocityY * 0.1,
duration: 0.3
});
}
});
// Dev tools for the observer-driven animation
GSDevTools.create({
minimal: true,
animation: gsap.getById("reactive-animation")
});