Jump to content
Search Community

Pinned sections with animation

zuppa test
Moderator Tag

Recommended Posts

My example is working in the way I want it, its just a little bit bugged ( ex: it was supossed to stop the black overlay from growing until the middle of the screen, and then it started scrolling, and appears the next slide), right now its overlaping the animations, but I'v made this using a padding-bottom, in wich I think it's not the best approach, how can I achieve this with GSAP's utils the correct way?

See the Pen BaQwGNb by msmzuppa (@msmzuppa) on CodePen

Link to comment
Share on other sites

  
gsap.registerPlugin(ScrollTrigger);
gsap.utils.toArray(".cascade .item").forEach(panel => {
  
  let fundo = panel.querySelector('.fundo')
  gsap.timeline({ //cria timeline
    scrollTrigger: {
      trigger: panel,
      scrub: true,
      pin: true,
      pinSpacing: false, 
    }
  }).to(fundo, { width: "100%"}); 
}); 

 

or with different syntax

 

  
gsap.registerPlugin(ScrollTrigger);
gsap.utils.toArray(".cascade .item").forEach(panel => {
  
  let fundo = panel.querySelector('.fundo')
  ScrollTrigger.create({
    trigger: panel,
    scrub: true,
    pin: true,
    pinSpacing: false,
    animation: gsap.to(fundo, { width: "100%"})
  })
}); 

 

• start: 'top top' is default

• setting an explicit duration of a scrub tween doesn't do much (they get default 0.5s, change it only if needed (not in this case))

• pinSpacing: false means you will start overlapping the next image, you have to somehow space them out if you don't want that

Link to comment
Share on other sites

 

Although it won't fix your issue, using tailbreezy's first code example above is a good idea. It's a little easier to read than what you have. In that same vein; using a proper formatting (this espacially with regard to your CSS) helps yourself and others wrap your head around what's going on more easily.

 

For the issue - I would probably handle it this way:

 

1) Instead of a padding-bottom: 100vw I would space the sections by using a margin-bottom: 100vh.

 

2) Create two seperate ScrollTriggers for each of your sections - one that handles the animation with an end of "+=100%" and another one that handles only the pinning - with an end of "+=200%" (twice the duration of the other trigger)

 

 

gsap.utils.toArray(".cascade .item").forEach(panel => {
  
  let fundo = panel.querySelector('.fundo')
  
  gsap.timeline({ //cria timeline
    scrollTrigger: {
      trigger: panel,
      scrub: true,
      start: 'top top',
      end: '+=100%'
    }
  }).to(fundo, { width: "100%"}); 
  
  ScrollTrigger.create({
      trigger: panel,
      pin: true,
      pinSpacing: false, 
      start: 'top top',
      end: '+=200%'
  })
  
});

 

See the Pen ebef6583695ca213ed451f4c5c3706f1 by akapowl (@akapowl) on CodePen

 

 

On a sidenote:

If you only have that single tween in that timeline, you could also just hook that scrollTrigger to a individual single tween instead of a timeline. And if you can, try to avoid tweening on properties such as width or height if possible - instead you could set the width you want and instead tween the scaleY from 0 to 1, for example - that should be more performant.

 

Hope this helps - and welcome to the forums :) 

 

  • Like 4
Link to comment
Share on other sites

6 minutes ago, ZachSaucier said:

This is incorrect. The default start value is "top bottom".

 

I did check my console, before I stated that.

 

  var st = ScrollTrigger.create({
    trigger: panel,
    scrub: true,
    start:'top top',
    pin: true,
    pinSpacing: false,
    animation: gsap.to(fundo, { width: "100%"})
  })
  
  console.log(st.start)

 

    start:'top top'

 

image.png.b6a11c2b1ef1d8782d2c94404b66616a.png

 

 

    start:'top bottom'

 

image.png.26640085ad0444c8bb9e9278b02cfd0c.png

 

//    not setting start: "..."

 

image.png.a356fbcbce1dce6b6b76b84ef382beb7.png

  • Like 1
Link to comment
Share on other sites

I like using them, they are much better experience. 

Having them available from everywhere is also huge for usability (key combo).

 

For example how to see the defaults for scrollTrigger pin.

I would prefer pressing Cmd+K, typing ScrollTrigger defaults, select the best option and go.

Right now I have to click the docs, wait for the http response (takes a few secs), click exactly over the input box, type ScrollTrigger (not that smart to understand scrolltrigger defaults), go to scrolltrigger plugin page, start scrolling (these pages are very long), and hopefully find what i need.

No bueno.

 

Link to comment
Share on other sites

4 hours ago, akapowl said:

 

Although it won't fix your issue, using tailbreezy's first code example above is a good idea. It's a little easier to read than what you have. In that same vein; using a proper formatting (this espacially with regard to your CSS) helps yourself and others wrap your head around what's going on more easily.

 

For the issue - I would probably handle it this way:

 

1) Instead of a padding-bottom: 100vw I would space the sections by using a margin-bottom: 100vh.

 

2) Create two seperate ScrollTriggers for each of your sections - one that handles the animation with an end of "+=100%" and another one that handles only the pinning - with an end of "+=200%" (twice the duration of the other trigger)

 

 


gsap.utils.toArray(".cascade .item").forEach(panel => {
  
  let fundo = panel.querySelector('.fundo')
  
  gsap.timeline({ //cria timeline
    scrollTrigger: {
      trigger: panel,
      scrub: true,
      start: 'top top',
      end: '+=100%'
    }
  }).to(fundo, { width: "100%"}); 
  
  ScrollTrigger.create({
      trigger: panel,
      pin: true,
      pinSpacing: false, 
      start: 'top top',
      end: '+=200%'
  })
  
});

 

 

 

 

 

On a sidenote:

If you only have that single tween in that timeline, you could also just hook that scrollTrigger to a individual single tween instead of a timeline. And if you can, try to avoid tweening on properties such as width or height if possible - instead you could set the width you want and instead tween the scaleY from 0 to 1, for example - that should be more performant.

 

Hope this helps - and welcome to the forums :) 

 

 

Thank you very much akapowl, and thank you all that entered this topic :) this works as I expected, but again, I have a question, can I do something like this?

I want to do this, because I have my menu bar above, and I don't want the items to be the height of the screen, but the height of the screen minus the menu bar height

 

end: '+=100% - ' +  $(".barramenu").height()

 

gsap.utils.toArray(".cascade .item").forEach(panel => {

  let fundo = panel.querySelector('.fundo') 
  gsap.timeline({ //cria timeline
    scrollTrigger: {
      trigger: panel,
      scrub: true,
      start: 'top top',
      end: '+=100% - ' + $(".barramenu").height()
    }
  }).to(fundo, { width: "100%"}); 

  ScrollTrigger.create({
    trigger: panel,
    pin: true,
    pinSpacing: false, 
    start: 'top top',
    end: '+=200% - ' + $(".barramenu").height()
  });
});


 

 

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...