Share Posted May 11, 2022 Hi, I've been experimenting with GSAP and I'm really excited. But from time to time I don't get any further, because unfortunately I don't yet understand all the mechanisms and parameters and I hope you have a tip for me. I want to achieve the following structure: 4 Sections scroll horizontally. The 3rd section stops and shows a text element list on the left and a graphic on the right. The user should navigate through the list by scrolling. The list moves up (disappears) and the next text list element is activated (opacity 1) and shows a different image on the right side. The list should not have a limited number of list text elements. This will be dynamically expanded later. If the last list text element is active, the user scrolls further to the right into the next section. I saw this on another website but unfortunately the mechanism wasn't built with GSAP so I wanted to see if it could be replicated. A Gif is attached. The background change in the animation is not necessary. Can I do this with GSAP? Thank you for your help See the Pen KKQMgZJ by dkx (@dkx) on CodePen Link to comment Share on other sites More sharing options...
Author Share Posted May 11, 2022 Ok i can now add the Gif example in post before Link to comment Share on other sites More sharing options...
Share Posted May 11, 2022 Hi DK7, It's best to think in terms of animations instead of scrolling. ScrollTrigger is just an animation controller, so you need to solve the animation problem before worrying about scrolling or anything else that ScrollTrigger does. You basically described everything you need to do for your timeline. Animate to the 3rd section Animate stuff in inside the 3rd section vertically Animate to the 4th section 1 Link to comment Share on other sites More sharing options...
Author Share Posted May 11, 2022 17 minutes ago, OSUblake said: Hi DK7, It's best to think in terms of animations instead of scrolling. ScrollTrigger is just an animation controller, so you need to solve the animation problem before worrying about scrolling or anything else that ScrollTrigger does. You basically described everything you need to do for your timeline. Animate to the 3rd section Animate stuff in inside the 3rd section vertically Animate to the 4th section Hi @OSUblake, thank you very much for your quick answer. I think I might have described it wrong. The animations are supposed to be triggered by scrolling. As soon as the user enters this section 3, the further downward scrolling should jump from link to link (i.e. vertically) and then horizontally at the end to the next section. I had already found out that theoretically I could simply make one section under the other for each text and then scroll through them. But then the other texts in the list above and below are missing in the visible area. I hope I could explain that a little better now. I've only been testing with GSAP for 2 days. I've only used gsap.to so far. The timelines are completely new to me. Although I had understood that timelines run through when triggered, right? That would mean that the user enters section 3 and then the links go through automatically, right? Or can I also control the timeline based on the scroll positions? Thank you very much for your help! Link to comment Share on other sites More sharing options...
Share Posted May 11, 2022 27 minutes ago, DK7 said: The animations are supposed to be triggered by scrolling. I know, but that's not important right now. Just focus on making the timeline. That's where a lot of new people mess up. They are approaching everything as if it's a scrolling problem, when in reality it's an animation problem. A timeline will work the same regardless of it's hooked up to ScrollTrigger on not. ScrollTrigger will scrub through a timeline just like everything else. Just think of ScrollTrigger as being like GSDevTools that you control with the scroll position. But again, don't focus on the scrolling part right now. If you make a timeline that does what I described below, I guarantee you it will work once you hook it up to ScrollTrigger. 55 minutes ago, OSUblake said: Animate to the 3rd section Animate stuff in inside the 3rd section vertically Animate to the 4th section 3 Link to comment Share on other sites More sharing options...
Share Posted May 11, 2022 Here's just a quick demo. I'm just animating scale on the 3rd slide to show that is where you do the animations for the vertical movement. See the Pen OJQXdBY by GreenSock (@GreenSock) on CodePen 5 Link to comment Share on other sites More sharing options...
Author Share Posted May 11, 2022 30 minutes ago, OSUblake said: Here's just a quick demo. I'm just animating scale on the 3rd slide to show that is where you do the animations for the vertical movement. That was exactly my problem! I couldn't understand how to pin Section 3 and then animate in it. Thank you very much for the example it really helps me a lot. Now I can continue and test here 2 Link to comment Share on other sites More sharing options...
Author Share Posted May 13, 2022 Hi @OSUblake and @Cassie, i need help please 🤯 In the last 2 days I've been studying the examples and common error pages of GSAP and unfortunately I can't get any further. That's because I still don't understand some basic things about GSAP. Can you explain this to me in a little more detail? Here is my current status. How can I insert a code pen in an answer here ^^ See the Pen JjpRgQY by dkx (@dkx) on CodePen 1. the original horizontal scroll effect was performed by this code: let sections = gsap.utils.toArray(".slide"); let scrollTween = gsap.to(sections, { xPercent: -100 * (sections.length - 1), ease: "none", scrollTrigger: { trigger: ".main-container", pin: true, scrub: 0.1, ends: "+=3000" } }); @OSUblake... replaced this with a timeline: let sections = gsap.utils.toArray(".slide"); let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", pin: true, scrub: 0.1, end: "+=2000" } }) .to(sections, { xPercent: -100 * 2, ease: "none", }); tl.to(".list-left", { scale: 0.5, yo-yo: true, repeat: 1 }); tl.to(sections, { xPercent: -100 * (sections.length - 1), ease: "none" }); I'm trying to understand this code now 🤔 The timeline and a scroll trigger for the complete content container of all horizontal sections are created first: let sections = gsap.utils.toArray(".slide"); let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", pin: true, scrub: 0.1, end: "+=2000" } }) but why does this code set the 3rd section pinned? If I replace the * 2 with a * 3, the 4th section is pinned. I just don't get the point no matter how hard I try to understand. Doesn't the code actually mean that each section gets an xPercent value of -100 * 2, i.e. -200? .to(sections, { xPercent: -100 * 2, ease: "none", }); After that comes this code: tl.to(".list-left", { scale: 0.5, yo-yo: true, repeat: 1 }); but why does a .to step have to come before tl.to(sections...) so that section 3 is pinned? If I remove this .to animation step, then the section does not remain fixed / pinned? I can also change this but I just can't remove it. I think my problem is, since GSAP is still totally new, that I don't yet have an overview of the context of the animations. My original plan, the scrollable list, is slowly but surely becoming functional. However, two things are not entirely clear to me: 1. Does the code I wrote make sense for this animation, or am I making it unnecessarily difficult? This question is important for me to assess whether I understand things correctly or not 2. Why is the "onEnter" callback triggered but not "onEnterBack" when scrolling back? 3. I just saw through the codepen that if the view is not like in my local test environment (1920x1080px monitor) then the scroll triggers don't work properly. Is it correct to work with % values here? How to fix this automatically in GSAP? GSAP is really an exciting topic! I'm looking forward to the day when I understand the technology behind it Thank you for your time and help 🙏 Link to comment Share on other sites More sharing options...
Share Posted May 13, 2022 2 hours ago, DK7 said: but why does this code set the 3rd section pinned? If I replace the * 2 with a * 3, the 4th section is pinned. I just don't get the point no matter how hard I try to understand. Doesn't the code actually mean that each section gets an xPercent value of -100 * 2, i.e. -200? I don't how familiar you are with arrays, but knowing that arrays are zero-based is key to understanding all that. Zero-based means the first item has an index of 0. So the second item would have an index of 1, the third item would have an index of 2, and so on. And think about it in terms of math. How many screen widths is the first panel away from the viewport? It's already in view, so that would be 0. The second panel is 1 screen width away, the third panel is 2 screen widths away and so on. And that's why you'll commonly see this calculation to do horizontal effects. xPercent: -100 * (sections.length - 1), We subtract 1 from the length because length is not zero-based. So if there are 5 sections, i.e. the array length, then the last section will have an index of 4. Yes, it can be confusing, but that's just how it is. 2 hours ago, DK7 said: but why does a .to step have to come before tl.to(sections...) so that section 3 is pinned? First off, that section is not being pinned. What is being pinned is the trigger you set here. let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", // this is what gets pinned pin: true, scrub: 0.1, end: "+=2000" } }) Throughout this thread, I've been trying to make it a point that you need to approach it as an animation problem and not a scrolling problem. So here's essentially what a horizontal animation would look like if you could scale it down. The red box is meant to represent the viewport of your screen. See the Pen ExQNKja by GreenSock (@GreenSock) on CodePen And ScrollTrigger is very similar to GSDDevTools in that it can scrub animations. If scrubbing that animation looks fine in GSDevTools, it will look the same if we hook it up to ScrollTrigger. See the Pen PoQbNje by GreenSock (@GreenSock) on CodePen So I would suggest trying to make a timeline just like I did. If it works without ScrollTrigger, it will work with it. That's a hint that you should not have any nested ScrollTriggers inside your timeline, like I see here. tl.to('.list-left ul', { scrollTrigger: { // !!! you should never have a nested ScrollTrigger trigger: '.list-left ul', start: "83% center", scrub: true, markers: true, }, ... }) See the most Common ScrollTrigger Mistakes for more information. And for the images, I would not change the src as you can't animate that. To do a crossfade you need to have all the images inside the DOM, and then absolutely positioned on top of each other. 5 Link to comment Share on other sites More sharing options...
Author Share Posted May 14, 2022 22 hours ago, OSUblake said: I don't how familiar you are with arrays, but knowing that arrays are zero-based is key to understanding all that. Zero-based means the first item has an index of 0. So the second item would have an index of 1, the third item would have an index of 2, and so on. And think about it in terms of math. How many screen widths is the first panel away from the viewport? It's already in view, so that would be 0. The second panel is 1 screen width away, the third panel is 2 screen widths away and so on. And that's why you'll commonly see this calculation to do horizontal effects. xPercent: -100 * (sections.length - 1), We subtract 1 from the length because length is not zero-based. So if there are 5 sections, i.e. the array length, then the last section will have an index of 4. Yes, it can be confusing, but that's just how it is. Aaaah ok now I understand the meaning behind it! Thank you for the detailed explanation! And through the "Sections" array, all the sections stored in the array get the .to() right? .to(sections, { xPercent: -100 * 2, ease: "none", }); In the end, you could also write it like this with 5 sections: tl.to(sections, { xPercent: -100 * (5 - 1), ease: "none" }); and this .to() is also given to all sections. So that would actually be xPercent: -100 * 4 right? But why does the timeline still have to animate ".left-side" so that the sections scroll horizontally? I don't quite understand that yet? We have: let sections = gsap.utils.toArray(".slide"); let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", pin: true, scrub: 0.1, end: "+=2000" } }) .to(sections, { xPercent: -100 * 2, ease: "none", }); tl.to(".list-left", { scale: 0.5, yo-yo: true, repeat: 1 }); tl.to(sections, { xPercent: -100 * (sections.length - 1), ease: "none" }); For the sake of clarity, a short summary: let tl = gsap.timeline .to sections tl .to list-left .to sections ".to list-left" could actually be deleted: let tl = gsap.timeline .to sections tl .to sections but then you could actually do it that way, or doesn't that work? let tl = gsap.timeline .to sections .to sections I think it is important for me as a beginner to understand the order. If I create a timeline and this is already assigned a .to() at the beginning, like this: let tl = gsap.timeline .to.... 1 what happens if I add something to this timeline later? So that's how: let tl = gsap.timeline .to... 1 ....... ....... ....... tl .to... 2 .to... 3 .to... 4 Then .to 1 is executed first and then .to 2 3 4, isn't it? And what I also noticed, some .to() only work if I use "gsap.to" instead of "tl.to". Can you briefly explain the difference to me? That would be great! Is "gsap" a kind of global timeline that encompasses everything? But creating a new timeline with: let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", pin: true, scrub: 0.1, end: "+=2000" } }) is then only from or for the scroll trigger element ".main-container"? 22 hours ago, OSUblake said: First off, that section is not being pinned. What is being pinned is the trigger you set here. let tl = gsap.timeline({ scrollTrigger: { trigger: ".main-container", // this is what gets pinned pin: true, scrub: 0.1, end: "+=2000" } }) Throughout this thread, I've been trying to make it a point that you need to approach it as an animation problem and not a scrolling problem. Ok I think I'm confusing the meaning of pinned. I thought pinned would be like e.g. in CSS fixed. The element is then positioned in a fixed manner. But fixed elements, for example, don't work at all within horizontal scroll areas, as I've noticed, right? I was able to use CSS: .logo{ position:fixed; left:20px; top:20px; } place a logo at the top left and all sections behind it are scrolled horizontally as normal. BUT I can't do CSS: .burgernav{ position:fixed; right:20px; top 20px; } to place a burger menu at the top right. No matter what I try, the element stays invisible. Why is that and how can I do that? 22 hours ago, OSUblake said: So here's essentially what a horizontal animation would look like if you could scale it down. The red box is meant to represent the viewport of your screen. And ScrollTrigger is very similar to GSDDevTools in that it can scrub animations. If scrubbing that animation looks fine in GSDevTools, it will look the same if we hook it up to ScrollTrigger. Ok the code is up to "gsap.registerPlugin(GSDevTools);" & "GSDevTools.create();" identical in these examples right? I haven't tried GSDevTools yet ^^ 22 hours ago, OSUblake said: So I would suggest trying to make a timeline just like I did. If it works without ScrollTrigger, it will work with it. Yes, I really want to do it the way you do - I'm LEARNING diligently every beginning is difficult If I understood your hint correctly, then I actually always have to build a timeline that plays all animations of the entire page one after the other when it should be a horizontal scroll mechanism. Only when everything looks so good automatically, i.e. when I press play or the timeline starts by itself, only then do I add scroll triggers in the code at the end? 22 hours ago, OSUblake said: That's a hint that you should not have any nested ScrollTriggers inside your timeline, like I see here. tl.to('.list-left ul', { scrollTrigger: { // !!! you should never have a nested ScrollTrigger trigger: '.list-left ul', start: "83% center", scrub: true, markers: true, }, ... }) That's an important tip thank you! 22 hours ago, OSUblake said: See the most Common ScrollTrigger Mistakes for more information. Yes, thanks! I've read it all several times and made my own "important list" of things I'm sure I'll need again at some point 22 hours ago, OSUblake said: And for the images, I would not change the src as you can't animate that. To do a crossfade you need to have all the images inside the DOM, and then absolutely positioned on top of each other. I would like to do that, but since the images should have background-size: cover via CSS, so that they always fill the entire container responsively (60% .right-side), I have to change the images via CSS. Unfortunately, IMG only supports "workarounds" which are not compatible with all browsers. But thanks for the tip! I apologize for my many questions and thank you for your patience and time! As a beginner to new techniques, I can only learn things from a pro like you. And I'm glad that you are doing such a great job here in the forum and that you are taking the time to help! Thank you very much 🙏 Link to comment Share on other sites More sharing options...
Share Posted May 15, 2022 There are a lot of questions here. Going from your questions about the difference between gsap.to and tl.to it seems like you're lacking in some core understanding. gsap.to is a tween and tl.to is for adding a tween to a timeline. These are two core concepts that are very important to understand before progressing further into other plugins. This is a great video for anyone getting started with GSAP. Can I suggest you take some time to watch it and then if you still have questions, pop back and we'll do our best to explain. Getting Started with GSAP from GreenSock on Vimeo. Additionally On 5/14/2022 at 6:39 PM, DK7 said: I would like to do that, but since the images should have background-size: cover via CSS, so that they always fill the entire container responsively (60% .right-side), I have to change the images via CSS. Unfortunately, IMG only supports "workarounds" which are not compatible with all browsers. But thanks for the tip! That's fine - all you have to do is put multiple divs into the HTML - as long as you have multiple elements you can crossfade them. 2 Link to comment Share on other sites More sharing options...
Author Share Posted May 21, 2022 On 5/15/2022 at 12:31 PM, Cassie said: There are a lot of questions here. Going from your questions about the difference between gsap.to and tl.to it seems like you're lacking in some core understanding. gsap.to is a tween and tl.to is for adding a tween to a timeline. These are two core concepts that are very important to understand before progressing further into other plugins. This is a great video for anyone getting started with GSAP. Can I suggest you take some time to watch it and then if you still have questions, pop back and we'll do our best to explain. Getting Started with GSAP from GreenSock on Vimeo. Additionally That's fine - all you have to do is put multiple divs into the HTML - as long as you have multiple elements you can crossfade them. Hi @Cassie, thank you very much for your help! The video was also very helpful I've watched it a few times now so that things stay in my memory 1 Link to comment Share on other sites More sharing options...
Share Posted May 22, 2022 Ah so glad to hear it was helpful. Awesome. And don't worry about keeping it in your memory. It's very normal to have to refer to the documentation. The important thing is to have a broad understanding of how everything fits together - then you can pop back to check out specifics. This cheatsheet may be useful too.https://greensock.com/cheatsheet/ 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now