Jump to content
Search Community

Scrolltrigger Animating Children using forEach()

kprkr test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

Hi all, so I am extremely new to the world of GSAP and have spent a few hours messing around and and browsing the forums, but I have run into a bit of a roadblock that may be an obvious fix, but I cannot seem to figured it out. Figured it was time I asked for some help.

 

So, on my page I have 3 sections. Something similar to this -

<div class"section-title">
	<h1>Title</h1>
	<p>Body Information</p>
</div>
<div class"section-title">
	<h1>Title</h1>
	<p>Body Information</p>
</div>
<div class"section-title">
	<h1>Title</h1>
	<p>Body Information</p>
</div>

What I am able to do, is use a forEach loop, and animate each section. Which is great, each .section-title loads its H1 and paragraph in at the same time.

However, what I would like to do, is be able to control the speed/delay of the H1 and paragraph within the section title.

 

Here is what I have working - 

 

However, I have tried messing with the code to select the H2 whilst still triggering at the .section-title, but when I do something such as -  

See the Pen poPdewL by _kprkr (@_kprkr) on CodePen

 

      const headers = gsap.utils.toArray('.group')
      // eslint-disable-next-line arrow-parens
      headers.forEach(header => {
        gsap.from('.section-header h1', {
          y: 40,
          opacity: 0,
          scrollTrigger: {
            trigger: header,
            start: 'top 50%',
            toggleActions: 'restart none none none',
            markers: true
          }
        })
      })

To grab and edit the H1, it works for the first one, exactly how I would like it to, but the 2nd and 3rd instances of it are already loaded in.

 

I have tried a variety of From, to, fromTo, etc and figured I am clearly not on the right path and wanted to see what the right way is, rather than bruteforcing it with 20 different triggers.

 

Thanks!

See the Pen qBmVrWg by _kprkr (@_kprkr) on CodePen

Link to comment
Share on other sites

Sorry, I am new to this site and its formatting and for some reason my first "working" example is displaying at the bottom of the post, followed by the broken, but more along the lines of what I am looking for, example. 

Link to comment
Share on other sites

  • Solution

You need to get the correct element references, and when working with any component framework, like Vue, you should never use GSAP's default selector as it searches the entire DOM. You should add refs...

<div class="group" ref="group1"></div>
// to access
gsap.to(this.$refs.group1, { ... })

 

Or use GSAP's selector util. You were using an older version so I had to update it.

 

See the Pen poPdrjd by GreenSock (@GreenSock) on CodePen

 

 

 

  • Like 2
Link to comment
Share on other sites

OSUblake you are a life saver, thank you so much! Cannot believe I spent so long trying to figure it out and the solution was so simple.

If I could ask you one more thing, if I were wanting to also add an animation to two H1 tags (an extra H1 under the current H1) as well as add an animation to the P tag, what would be the best way to do that?

Would it be a case of using a .timeline at the .group level rather than using;

gsap.from(header.querySelector("h1"),"

I ask this, because I implemented your changes above (which worked, thank you again!)

But, feel that maybe this is a lot of code to animate 3 elements in each ".group" and just wondering if there is a better way I should approach this scenario?

    animateOnScroll () {
      const q = this.$gsap.utils.selector(this.$el)
      // const tl = this.$gsap.timeline()
      const gsap = this.$gsap
      // eslint-disable-next-line arrow-parens
      q('.section-header').forEach(header => {
        gsap.from(header.querySelector('h2:nth-of-type(1)'), 0.8, {
          y: 40,
          opacity: 0,
          skewY: 7,
          scrollTrigger: {
            trigger: header,
            start: 'top 50%',
            toggleActions: 'restart none none none',
            markers: true
          }
        })
        gsap.from(header.querySelector('h2:nth-of-type(2)'), 0.8, {
          y: 40,
          opacity: 0,
          skewY: 7,
          delay: 0.3,
          scrollTrigger: {
            trigger: header,
            start: 'top 50%',
            toggleActions: 'restart none none none',
            markers: true
          }
        })
        gsap.from(header.querySelector('p'), 0.8, {
          y: 40,
          opacity: 0,
          delay: 0.6,
          scrollTrigger: {
            trigger: header,
            start: 'top 50%',
            toggleActions: 'restart none none none',
            markers: true
          }
        })
      })
    }

 

Edited by kprkr
added context
Link to comment
Share on other sites

const q = gsap.utils.selector(this.$el);
      q(".group").forEach(header => {
        let tl = gsap.timeline({
          scrollTrigger: {
            trigger: header,
            start: 'top 50%',
            toggleActions: 'restart none none none',
            markers: true
          }}) 
        tl.from(header.querySelector("h1"), {
          y: 40,
          opacity: 0,
        })
        .from(header.querySelector("h2"), {
          y: 40,
          opacity: 0,
        })
        .from(header.querySelector("p"), {
          y: 40,
          opacity: 0,
        })
      })

Hey @kprkr - yep, you'd probably be looking at creating a timeline like this. You can position tweens on the timeline using the position parameter.

Little accessibility note. You shouldn't ever have an h1 following an h1.  - Ideally you should only have one h1 per page or per section

  • Like 4
Link to comment
Share on other sites

@Cassie thank you so much, works perfectly!

And, yeah I agree double H1 is not ideal. Right now I am breaking a single title-line into 2, so I can edit them independently but I should probably do something more along the lines of 

<h1>
  <span>Line One</span>
  <span>Line Two</span>
</h1>
<p>Body text here</p>

Right?

 

Again, thank you Cassie you have saved me much headache!

  • Like 1
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...