Up And Running with GSAP
Read the Docs
Use the CDN
html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script> Create a Types file:
ts
// Type definitions for GSAP and ScrollTrigger
declare namespace gsap {
interface TweenVars {
[key: string]: any;
delay?: number;
duration?: number;
ease?: string | gsap.EaseFunction;
onComplete?: gsap.Callback;
onStart?: gsap.Callback;
onUpdate?: gsap.Callback;
x?: number | string;
y?: number | string;
scale?: number;
opacity?: number;
transformOrigin?: string;
}
interface Callback {
(): void;
}
interface EaseFunction {
(amount: number): number;
}
interface Tween {
kill(): void;
pause(): void;
play(): void;
progress(value?: number): number | this;
restart(includeDelay?: boolean, suppressEvents?: boolean): this;
resume(): this;
reverse(): this;
seek(time: number, suppressEvents?: boolean): this;
time(value?: number, suppressEvents?: boolean): number | this;
totalTime(value?: number, suppressEvents?: boolean): number | this;
}
interface TimelineVars {
[key: string]: any;
delay?: number;
onComplete?: Callback;
onStart?: Callback;
onUpdate?: Callback;
scrollTrigger?: ScrollTrigger.Vars;
autoRemoveChildren?: boolean;
defaults?: TweenVars;
}
interface Timeline extends Tween {
to(target: any, vars: TweenVars): this;
from(target: any, vars: TweenVars): this;
fromTo(target: any, fromVars: TweenVars, toVars: TweenVars): this;
set(target: any, vars: TweenVars): this;
}
interface Core {
to(target: any, duration: number, vars: TweenVars): Tween;
from(target: any, duration: number, vars: TweenVars): Tween;
fromTo(target: any, duration: number, fromVars: TweenVars, toVars: TweenVars): Tween;
set(target: any, vars: TweenVars): Tween;
timeline(vars?: TimelineVars): Timeline;
registerPlugin(plugin: any): void;
}
interface ScrollTrigger {
static create(vars: ScrollTrigger.Vars): ScrollTrigger.Instance;
static getAll(): ScrollTrigger.Instance[];
static refresh(): void;
static update(): void;
static clearMatchMedia(): void;
static config(vars: ScrollTrigger.StaticVars): void;
static register(plugin: any): void;
static registerPersistence(plugin: any): void;
static sort(): void;
static updateAll(): void;
static getById(id: string): ScrollTrigger.Instance | null;
static isInViewport(element: Element | string, percent?: number): boolean;
static maxScroll(element: Element | string, horizontal?: boolean): number;
static positionInViewport(element: Element | string, viewport?: Element): { x: number; y: number };
static scrollRounded(roundingIncrement: number): void;
static setScrollRounded(roundingIncrement: number): void;
}
namespace ScrollTrigger {
interface Vars {
trigger?: Element | string;
start?: string | number | (() => string | number);
end?: string | number | (() => string | number);
scrub?: boolean | number;
snap?: any;
onEnter?: Callback;
onLeave?: Callback;
onEnterBack?: Callback;
onLeaveBack?: Callback;
onUpdate?: (self: Instance) => void;
onToggle?: (self: Instance) => void;
onRefresh?: (self: Instance) => void;
onScrubComplete?: (self: Instance) => void;
onSnapComplete?: (self: Instance) => void;
onRefreshInit?: (self: Instance) => void;
onKill?: (self: Instance) => void;
markers?: boolean | object;
id?: string;
}
interface StaticVars {
limitCallbacks?: boolean;
autoRefreshEvents?: string;
}
interface Instance {
animation?: any;
direction: number;
end: number;
isActive: boolean;
progress: number;
scroller: Element;
start: number;
trigger: Element;
vars: Vars;
disable: (refresh?: boolean) => void;
enable: (refresh?: boolean) => void;
getVelocity: () => number;
getScroll: () => number;
isInViewport: (percent?: number) => boolean;
kill: () => void;
refresh: () => void;
revert: () => void;
tween: Tween;
tweenTo: (position: any) => Tween;
update: () => void;
}
}
}
declare const gsap: gsap.Core;
declare module 'gsap' {
export = gsap;
export as namespace gsap;
}
declare module 'gsap/ScrollTrigger' {
export = gsap.ScrollTrigger;
export as namespace ScrollTrigger;
}
declare global {
interface Window {
gsap: typeof gsap;
ScrollTrigger: typeof gsap.ScrollTrigger;
}
} css
.header {
position: sticky;
top: 0;
background: white;
padding: 20px;
text-align: center;
z-index: 1000;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
} css
.logo {
width: 400px; /* Fixed width - never changes */
transition: transform 0.3s ease;
transform-origin: center;
} js
function updateLogoSize() {
const scrollY = window.scrollY;
const maxScroll = 800; // Shrink over first 800px
const scrollProgress = Math.min(scrollY / maxScroll, 1);
// Scale from 1.0 (100%) to 0.3 (30%)
const scale = 1 - (scrollProgress * 0.7);
logo.style.transform = `scale(${scale})`;
}