Jump to content
Search Community

GSAP ScrollTrigger Loop Through Array

Matthew Meaklim test
Moderator Tag

Go to solution Solved by Cassie,

Recommended Posts

Hello,

 

I'll try keep this as short as possible...

 

I've been working on this website, https://ilimitado.studio/, and am trying to add a simple ScrollTrigger animation to each project element - I've based my code off the CodePen above, but it's not quite working as expected.

 

Here's my code:

 

const projects              =   gsap.utils.toArray('.project');
const imageRevealWrapper    =   gsap.utils.toArray('.image-reveal_wrapper');
const imageRevealImage      =   gsap.utils.toArray('.image-reveal .image');

projects.forEach((project, i) => {
  const transitionOne     =   gsap.fromTo(imageRevealWrapper, {y: '30%', z: 0, rotationX: -45, opacity: 0}, {y: 0, z: 0, rotationX: 0, opacity: 1, duration: .9});
  const transitionTwo     =   gsap.fromTo(imageRevealImage, {scale: 1.2}, {scale: 1, duration: 1.2, delay: .3});

  ScrollTrigger.create({
    scroller: '[data-scroll-container]',
    trigger: project,
    animation: transitionOne,
    once: true,
    ease: 'cubic-bezier(.435, .250, .150, .965)'
  });

  ScrollTrigger.create({
    scroller: '[data-scroll-container]',
    trigger: project,
    animation: transitionTwo,
    once: true,
    ease: 'cubic-bezier(.435, .250, .150, .965)'
  });
});

If you head to the above URL, I've left the effect in on the "Adele's Apothecary" project element so you can see the madness.

Basically, the animation fires each and every time I reach a project, whereas I only want it to fire once per project.

 

Thanks,

 

Matthew

See the Pen eYJZbJN by Meuss (@Meuss) on CodePen

Link to comment
Share on other sites

Hi Matthew! Lovely site - and don't worry, we got you, this is just a scoping thing.

 

const projects              =   gsap.utils.toArray('.project');
// these are global, and arrays
const imageRevealWrapper    =   gsap.utils.toArray('.image-reveal_wrapper');
const imageRevealImage      =   gsap.utils.toArray('.image-reveal .image');

// you're looping around which is great...
projects.forEach((project, i) => {
  // But then you're targeting ALL the images every time
  const transitionOne     =   gsap.fromTo(imageRevealWrapper, {y: '30%', z: 0, rotationX: -45, opacity: 0}, {y: 0, z: 0, rotationX: 0, opacity: 1, duration: .9});
  const transitionTwo     =   gsap.fromTo(imageRevealImage, {scale: 1.2}, {scale: 1, duration: 1.2, delay: .3});

  ScrollTrigger.create({
    scroller: '[data-scroll-container]',
    trigger: project,
    animation: transitionOne,
    once: true,
    ease: 'cubic-bezier(.435, .250, .150, .965)'
  });

  ScrollTrigger.create({
    scroller: '[data-scroll-container]',
    trigger: project,
    animation: transitionTwo,
    once: true,
    ease: 'cubic-bezier(.435, .250, .150, .965)' // this isn't valid, eases don't go in the scrolltrigger object and this isn't the correct syntax - this is CSS easing.
  });
});


This should be more like it...
 

// grab all this projects
const projects = gsap.utils.toArray(".project");

// loopy loop...
projects.forEach((project, i) => {
  // grab the image bits that are inside this project element
  const imageRevealWrapper = project.querySelector(".image-reveal_wrapper");
  const imageRevealImage = project.querySelector(".image-reveal .image");

  // a timeline is probably best here as they're triggering at the same time
  let tl = gsap.timeline({
    scrollTrigger: {
      scroller: "[data-scroll-container]",
      trigger: project,
    }
  })
  // you also might not need fromTop tweens, they're often unnessecary. Unsure without seeing the CSS
  tl.from(imageRevealWrapper, {
    yPercent: 30,
    rotationX: -45,
    opacity: 0,
    duration: 0.9,
    ease: "power2.inOut"
  }).from(imageRevealImage, {
    scale: 1.2,
    duration: 1.2,
    delay: 0.3,
    ease: "power2.inOut"
  }, 0);
});


Hope this helps!

  • Like 1
Link to comment
Share on other sites

Hi Cassie,

 

Thanks for the quick reply.

 

I still couldn't get it to work, but I've went ahead and set up a CodePen in the hope it makes a fix that bit easier. I currently have your JS in, and mine commented out just below. I'm assuming my CSS is preventing the first .project element from showing, but it looks like the JS isn't looping through as expected as the other three .project elements do still show.

 

See the Pen yLRNgrg by ilimitadostudio (@ilimitadostudio) on CodePen

 

Thanks,

 

Matthew

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...