Skip to content

Instantly share code, notes, and snippets.

@pieter-biesemans
Created August 11, 2023 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pieter-biesemans/bdd437d02e722d2c3bc8de61371bf85e to your computer and use it in GitHub Desktop.
Save pieter-biesemans/bdd437d02e722d2c3bc8de61371bf85e to your computer and use it in GitHub Desktop.
GSAP Animate On Scroll
//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