Animate Item Based On Position Within Parent
Utility
GSAP
JS
- Animate item based on its horizontal position within parent
- When .item is horizontally centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or horizontal scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.right - rect.left) / (rect.width + compRect.width)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>- Animate item based on its vertical position within parent
- When .item is vertically centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.bottom - rect.top) / (rect.height + compRect.height)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>Preview Links
Custom JS
Enable custom code in preview or view on published site.
Enable custom code?
Last Updated: Dec 3, 2025
- Animate item based on its horizontal position within parent
- When .item is horizontally centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or horizontal scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.right - rect.left) / (rect.width + compRect.width)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>- Animate item based on its vertical position within parent
- When .item is vertically centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.bottom - rect.top) / (rect.height + compRect.height)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>