Created
August 11, 2023 07:42
-
-
Save pieter-biesemans/bdd437d02e722d2c3bc8de61371bf85e to your computer and use it in GitHub Desktop.
GSAP Animate On Scroll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Prefers reduced motion check | |
let reduceMotion = window.matchMedia('(prefers-reduced-motion)').matches; | |
//create a traversable array of all the items with the animation data attr | |
const animateItems = gsap.utils.toArray('[data-in], [data-out]'); | |
//add the animation to each item in the array | |
animateItems.forEach((item, i) => { | |
//respect reduced motion request | |
if (reduceMotion) return false; | |
//save the item's data attributes | |
let data = item.dataset; | |
//set default values for the data attributes | |
let inStart = "top bottom", | |
inEnd = "bottom bottom", | |
outStart = "top top", | |
outEnd = "bottom top"; | |
//set the data for the ScrollTrigger plugin | |
let stInData = { | |
trigger: item, | |
start: data['start'] || data['in-start'] || inStart, | |
end: data['end'] || data['in-end'] || inEnd, | |
once: data.once == "true" ? true : false, | |
scrub: data.scrub ? (data.scrub * 1) : true, | |
markers: data.debug == "true" ? true : false, | |
overwrite: "auto" | |
}; | |
let stOutData = { | |
trigger: item, | |
start: data['out-start'] || outStart, | |
end: data['out-end'] || outEnd, | |
once: data.once == "true" ? true : false, | |
scrub: data.scrub ? (data.scrub * 1) : true, | |
markers: data.debug == "true" ? true : false, | |
overwrite: "auto" | |
}; | |
//create a function to add the animations | |
function animate(item, animation, properties, stData) { | |
if (data.in === animation) { | |
gsap.set(item, properties.set); | |
gsap.to(item, { | |
duration: 1, | |
...properties.to, | |
scrollTrigger: stData, | |
}); | |
} | |
if (data.out === animation) { | |
gsap.to(item, { | |
duration: 1, | |
...properties.to, | |
scrollTrigger: stData, | |
}); | |
} | |
} | |
//define the animations with their properties | |
const animations = [ | |
//IN animations | |
{ | |
type: 'fade-in', | |
properties: { | |
set: { autoAlpha: 0 }, | |
to: { autoAlpha: 1 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fade-in-up', | |
properties: { | |
set: { autoAlpha: 0, y: 50 }, | |
to: { autoAlpha: 1, y: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fade-in-down', | |
properties: { | |
set: { autoAlpha: 0, y: -50 }, | |
to: { autoAlpha: 1, y: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fade-in-left', | |
properties: { | |
set: { autoAlpha: 0, x: -50 }, | |
to: { autoAlpha: 1, x: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fade-in-right', | |
properties: { | |
set: { autoAlpha: 0, x: 50 }, | |
to: { autoAlpha: 1, x: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fly-in', | |
properties: { | |
set: { x: -50 }, | |
to: { x: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fly-in-left', | |
properties: { | |
set: { x: -50 }, | |
to: { x: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'fly-in-right', | |
properties: { | |
set: { x: 50 }, | |
to: { x: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'zoom-in', | |
properties: { | |
set: { scale: 0.25 }, | |
to: { scale: 1 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'zoom-in-up', | |
properties: { | |
set: { scale: 0.25, y: 150 }, | |
to: { scale: 1, y: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'zoom-in-down', | |
properties: { | |
set: { scale: 0.25, y: -150 }, | |
to: { scale: 1, y: 0 }, | |
}, | |
stData: stInData, | |
}, | |
{ | |
type: 'rotate-in', | |
properties: { | |
set: { rotate: (data.rotate || 360) + 'deg' }, | |
to: { rotate: 0 }, | |
}, | |
stData: stInData, | |
}, | |
//OUT animations | |
{ | |
type: 'fade-out', | |
properties: { | |
to: { autoAlpha: 0, visibility: "visible", immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fade-out-up', | |
properties: { | |
to: { autoAlpha: 0, y: -50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fade-out-down', | |
properties: { | |
to: { autoAlpha: 0, y: 50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fade-out-left', | |
properties: { | |
to: { autoAlpha: 0, x: -50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fade-out-right', | |
properties: { | |
to: { autoAlpha: 0, x: 50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fly-out', | |
properties: { | |
to: { x: -50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fly-out-left', | |
properties: { | |
to: { x: -50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'fly-out-right', | |
properties: { | |
to: { x: 50, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'zoom-out', | |
properties: { | |
to: { scale: 0.25, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'zoom-out-up', | |
properties: { | |
to: { scale: 0.25, y: -150, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'zoom-out-down', | |
properties: { | |
to: { scale: 0.25, y: 150, immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
{ | |
type: 'rotate-out', | |
properties: { | |
to: { rotate: (data.rotate || 360) + 'deg', immediateRender: false }, | |
}, | |
stData: stOutData, | |
}, | |
]; | |
//add the animations from the array | |
animations.forEach(({type, properties, stData}) => { | |
animate(item, type, properties, stData); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment