ScrollTrigger pin and progress
-
Learn how to pin sections during scroll and track animation progress using ScrollTrigger
pinandprogress.
Introduction
Two of the most powerful ScrollTrigger features are:
-
pin→ keeps an element fixed while scrolling -
progress→ tells how much of the scroll animation is completed
Together, they help you build:
-
Storytelling pages
-
Step-by-step sections
-
Scroll-based progress indicators
-
What is
pin?pinlocks an element in place while the user scrolls.
ScrollTrigger.create({
trigger: ".section",
pin: true
});
What is
progress?progressshows how far the scroll animation has progressed.-
Value range:
0→1 -
0= animation just started -
1= animation fully completed
📌 Available inside callbacks like
onUpdate.-
Basic Syntax (Pin + Progress)
ScrollTrigger.create({
trigger: ".panel",
start: "top top",
end: "+=400",
pin: true,
onUpdate: (self) => {
console.log(self.progress);
}
});
Pin a Section While Scrolling
ScrollTrigger.create({
trigger: ".panel",
start: "top top",
end: "+=500",
pin: true
});
Scroll Progress Bar
ScrollTrigger.create({
trigger: ".content",
start: "top top",
end: "bottom bottom",
onUpdate: (self) => {
gsap.to(".progress-bar", {
scaleX: self.progress,
transformOrigin: "left"
});
}
});
Pin Section + Animate Based on Progress
ScrollTrigger.create({
trigger: ".slide",
start: "top top",
end: "+=300",
pin: true,
scrub: true,
onUpdate: (self) => {
gsap.to(".image", {
scale: 0.8 + self.progress * 0.2
});
}
});
Key Properties Used with Pin
Property Purpose pin Fix element during scroll end Defines pin duration scrub Sync animation with scroll pinSpacing Add/remove space after pin markers Debug start/end
Note:
Common Mistakes
-
❌ Forgetting to define
endwithpin -
❌ Heavy animations inside
onUpdate -
❌ Not using
scrubwhen needed -
❌ Pinning too many sections
-
❌ Ignoring mobile behavior