delivous Posted May 11, 2022 Share Posted May 11, 2022 I'm working on a project that has multiple ScrollTriggers with long timelines. Everything works fine until the end of the pinned container. Once you reach the end of the container, the contents jumps to the bottom. I've created a pen showing the method I'm using to create the ScrollTriggers and the timelines. However, I wasn't able to recreate the issue on codepen. Below is the screen recording of the issue. Also, while I was trying to record this video I tried it on fullscreen first and apparently the issue disappeared. Any idea what could be causing this? Thanks in advance! See the Pen gOvMNdP?editors=0010 by delivious (@delivious) on CodePen Link to comment Share on other sites More sharing options...
OSUblake Posted May 11, 2022 Share Posted May 11, 2022 Welcome to the forums @delivous It's really hard to advise without having some sort of demo that can reproduce the issue. I would suggest trying to isolate the problem, commenting out code until figure out what the culprit is. 1 Link to comment Share on other sites More sharing options...
delivous Posted May 11, 2022 Author Share Posted May 11, 2022 Hey @OSUblake, Really appreciate your quick response. I just uploaded the project to a server(https://delivious.000webhostapp.com/safety-tech.php) and the issue has disappeared. I can only recreate this issue locally. Really strange! Link to comment Share on other sites More sharing options...
OSUblake Posted May 11, 2022 Share Posted May 11, 2022 Strange indeed. I noticed that your site has scroll-behavior: smooth on it. I'm wondering if that might be messing with something somehow. 1 Link to comment Share on other sites More sharing options...
delivous Posted May 11, 2022 Author Share Posted May 11, 2022 Thank you for having a look at it. I did overwrite those declarations, however the issue is still there. I also tried commenting out everything but that didn't help either. Link to comment Share on other sites More sharing options...
GreenSock Posted May 11, 2022 Share Posted May 11, 2022 Are you absolutely positive you're using the latest version of all GSAP files (3.10.4 as of right now)? Maybe try: console.log(ScrollTrigger.version) 1 Link to comment Share on other sites More sharing options...
delivous Posted May 11, 2022 Author Share Posted May 11, 2022 Hey @GreenSock, Yes, I just checked, the version is latest - 3.10.4. Link to comment Share on other sites More sharing options...
GreenSock Posted May 11, 2022 Share Posted May 11, 2022 Hm. I'm not sure what to say - it's virtually impossible for us to troubleshoot if we can't reproduce it somehow. There must be something unique about your local environment there. 🤷♂️ 1 Link to comment Share on other sites More sharing options...
delivous Posted May 12, 2022 Author Share Posted May 12, 2022 Hey @GreenSock, I understand. I tried coding the whole timeline again and found out that when I add this tween(at the end of the timeline) below is when the issue begins. i.e, the contents of the pinned container jumps offscreen to the bottom. .fromTo('#prop_25', { scale: 1, }, { scrollTrigger: { start: () => {pos += normH; return pos;}, end: () => {pos += normH; return pos;}, scrub: 0.5 }, scale: 3, ease: "expo.inOut" }); As soon as I remove this tween, everything works fine. This isn't the only tween that's animating the scale value. I'm not sure how this could affect the pinned container. I'm also setting display: flex and overflow: hidden to the pinned container, if that helps. Link to comment Share on other sites More sharing options...
Cassie Posted May 12, 2022 Share Posted May 12, 2022 Is that a nested scrollTrigger by any chance? You shouldn't have ScrollTriggered tweens inside a ScrollTriggered timeline. Big no-no! 1 Link to comment Share on other sites More sharing options...
delivous Posted May 12, 2022 Author Share Posted May 12, 2022 Hey @Cassie, Thank you for your response. I'm using the same technique used in this codepen( See the Pen PoZKRLd?editors=0010 by Sicontis (@Sicontis) on CodePen ). Actually, I've found the issue. The element('#prop_25') was a <figure> element, I changed it to a <div> and that fixed it. Link to comment Share on other sites More sharing options...
delivous Posted May 12, 2022 Author Share Posted May 12, 2022 18 minutes ago, Cassie said: You shouldn't have ScrollTriggered tweens inside a ScrollTriggered timeline. Big no-no! Apologies I forgot to mention the changes. In the previous version, I had ScrollTriggered timeline and when I ran into this issue I decided to replace them with the ScrollTriggered tweens hoping that might solve the issue. But actually the culprit was the <figure> element. Thank you all for your help! Really appreciated! 1 Link to comment Share on other sites More sharing options...
Cassie Posted May 12, 2022 Share Posted May 12, 2022 I've never seen timelines with a mixture of scrollTriggered tweens and non-scrollTriggered tweens added to them before. Seems to be working but I'm not quite sure how? Tweens on a timeline are meant to be sequenced after one another whereas tweens with ScrollTriggers are triggered by a certain scroll position, so that's conflicting logic in my head... 1 Link to comment Share on other sites More sharing options...
delivous Posted May 13, 2022 Author Share Posted May 13, 2022 10 hours ago, Cassie said: I've never seen timelines with a mixture of scrollTriggered tweens and non-scrollTriggered tweens added to them before. Seems to be working but I'm not quite sure how? Tweens on a timeline are meant to be sequenced after one another whereas tweens with ScrollTriggers are triggered by a certain scroll position, so that's conflicting logic in my head... Hey @Cassie, Thank you for pointing that out. I was still facing issues, it was definitely how I was creating the timelines. After having a look at some examples, I redid everything again and it's working fine as expected now. Again really appreciate your help, Cheers! Link to comment Share on other sites More sharing options...
delivous Posted May 13, 2022 Author Share Posted May 13, 2022 Hey @OSUblake @GreenSock@Cassie, First of all I'm really sorry that I've made some quick assumptions before tracking down the real issue. After quite some back and forth; and restructuring the timelines, I noticed that the issue appears but only sometimes. As you can see in the screen recording(https://vimeo.com/709507484), when I keep refreshing the page a few times, the pinned section's start point sometimes starts at the start of the previous container or sometimes where it is expected to. As previously mentioned, if the start point is shifted and I switch to fullscreen, the "start" point magically snaps back to where it is supposed to be. When I switch back to normal window, the start point doesn't snap back to top but stays where it is expected to be. Assuming that the previous container's styling might be conflicting, I tried removing the previous section, but it does the same thing again but now with the very first section.i.e, the carousel. So maybe it's the way I'm creating the timeline? At this point, I'm quite clueless as I've tried almost everything I can but haven't been able to figure out why this is happening. It'd be really great if someone could help me get to the bottom of this. Again, as I'm not able to reproduce this issue on codepen, I'm attaching a minimal demo of how I'm structuring the timelines as well the updated live project(https://delivious.000webhostapp.com/safety-tech.php). See the Pen LYQRwLP?editors=0010 by delivious (@delivious) on CodePen Below is the full ScrollTrigger timeline logic: (function() { 'use strict'; const ease_in = "circ.in"; const ease_out = "circ.out"; const ease_in_out = "circ.inOut"; const expo_in = "expo.in"; const expo_out = "expo.out"; const expo_in_out = "expo.inOut"; let boxer_tl, mobile, ww; let _a = { init: () => { _a.initVars(); _a.initTimelines(); _a.createTimeline(); _a.attachEvents(); }, initVars: () => { ww = window.innerWidth; mobile = ww < 768; }, initTimelines: () => { gsap.registerPlugin("ScrollTrigger"); boxer_tl = gsap.timeline({ defaults: { duration: 0.67, ease: ease_out }, scrollTrigger: { trigger: ".boxerSection", start: "top top", end: "+=15000", markers: true, pin: true, scrub: 0.5 } }); }, createTimeline: () => { boxer_tl.set("#boxer_svg, #subaru_boxer_engine, #subaru_boxer_engine_inner, .prop, #car_2_engine_1, #car_2_engine_2", {opacity: 0, autoAlpha: 0}) .set("#boxer_title, .prop-conclude, .fullTitle, #prop_22, #prop_23, #prop_24, #prop_25, #prop_27, #prop_28, #prop_29, #prop_30, #prop_31, #prop_32", {yPercent: 100, opacity: 0, autoAlpha: 0}) .set("#subaru_car", {scale: 0, opacity: 0, autoAlpha: 0, transformOrigin: "center center"}) .set("#prop_1, #prop_2", {xPercent: mobile ? -20 : -50}) .set("#prop_3", {scale: 0, xPercent: mobile ? -300 : 100, yPercent: mobile ? 0 : -50, transformOrigin: "center center"}) .set("#car_2", {scale: 0, transformOrigin: "center center"}) .set("#prop_10", {yPercent: mobile ? 500 : 100}) .set("#prop_20", {yPercent: 0, opacity: 1, autoAlpha: 1}); boxer_tl.add("boxer_intro", mobile ? 0.1 : 0.2) .to("#boxer_title", {yPercent: -50, opacity: 1, autoAlpha: 1}, "boxer_intro") .fromTo("#boxer_title", {yPercent: -50, opacity: 1, autoAlpha: 1, ease: expo_in}, {yPercent: -100, opacity: 0, autoAlpha: 0, ease: ease_in}, "boxer_intro+=0.5") .add("figure_in") .to("#boxer_svg", {opacity: 1, autoAlpha: 1}, "figure_in") .to("#subaru_car", {scale: 1, opacity: 1, autoAlpha: 1, transformOrigin: "center center"}, "-=0.5") .add("boxer_engine") .to("#subaru_boxer_engine", {opacity: 1, autoAlpha: 1}, "boxer_engine") // you've got a smooth operator .to("#prop_1", {opacity: 1, autoAlpha: 1, xPercent: 0}, "-=0.25") .to("#prop_2", {opacity: 1, autoAlpha: 1, xPercent: 0}, "-=0.25") .fromTo("#prop_2", {opacity: 1, autoAlpha: 1, xPercent: 0, ease: ease_in}, {opacity: 0, autoAlpha: 0, xPercent: mobile ? 150 : -150}, "+=0.5") .fromTo("#prop_1", {opacity: 1, autoAlpha: 1, xPercent: 0, ease: ease_in}, {opacity: 0, autoAlpha: 0, xPercent: mobile ? 150 : -150}, "-=0.25") .to("#prop_3", {scale: 1, opacity: 1, autoAlpha: 1, xPercent: 0, yPercent: mobile ? 0 : -50}, "-=0.75") // boxer engine .to("#subaru_boxer_engine_inner", {opacity: 1, autoAlpha: 1}) .to("#prop_4", {opacity: 1, autoAlpha: 1}, "-=0.67") .to("#prop_5", {opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo("#prop_5", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0}, "+=0.5") .fromTo("#prop_4", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0}, "-=0.25") .fromTo("#subaru_car", {scale: 1, opacity: 1, autoAlpha: 1, transformOrigin: "center center", ease: ease_in}, {scale: 0, opacity: 0, autoAlpha: 0, transformOrigin: "center center"}, "-=0.67") // inline engine .add("inline_engine", "-=0.67") .to("#car_2", {scale: 1, opacity: 1, autoAlpha: 1, transformOrigin: "center center"}) .to("#car_2_engine_1", {opacity: 1, autoAlpha: 1}) .to("#prop_6", {opacity: 1, autoAlpha: 1}, "-=0.67") .to("#prop_7", {opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo("#prop_7", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0}, "+=0.5") .fromTo("#prop_6", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0}, "-=0.25") .fromTo("#car_2_engine_1", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0}) // v type engine .add("v_type_engine") .to("#car_2_engine_2", {opacity: 1, autoAlpha: 1}) .to("#prop_8", {opacity: 1, autoAlpha: 1}, "-=0.67") .to("#prop_9", {opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo("#prop_9", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0, xPercent: mobile ? 0 : 100, yPercent: mobile ? -400 : 0}, mobile ? "+=0.5" : "+=0.5") .fromTo("#prop_8", {opacity: 1, autoAlpha: 1, ease: ease_in}, {opacity: 0, autoAlpha: 0, xPercent: mobile ? 0 : 100, yPercent: mobile ? -1500 : 0}, mobile ? "-=0.67" : "-=0.5") // clear the scene for next phase .add("clear_engine_scene") .fromTo("#prop_3", {opacity: 1, autoAlpha: 1, xPercent: 0, yPercent: mobile ? 0 : -50, ease: expo_in}, {opacity: 0, autoAlpha: 0, xPercent: mobile ? 0 : -100, yPercent: mobile ? -250 : -50}, mobile ? "-=0.84" : "-=0.84") .fromTo("#boxer_svg", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: expo_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "-=0.5") // conclude .add("conclude", "-=0.67") .to("#prop_10", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_11", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_12", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_13", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_14", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_15", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_16", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_17", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .to("#prop_18", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") // clear conclude .add("clear_conclude") .to("#prop_20", {yPercent: -100, opacity: 0, autoAlpha: 0, ease: expo_in}) // lineartronic cvt .add("lineartronic_cvt") .to("#prop_19", {yPercent: -50, opacity: 1, autoAlpha: 1}, "lineartronic_cvt") .to("#prop_19", {yPercent: -100, opacity: 0, autoAlpha: 0, ease: ease_in}, "lineartronic_cvt+=1") .to("#prop_21", {yPercent: -50, opacity: 1, autoAlpha: 1}) .to("#prop_21", {yPercent: -100, opacity: 0, autoAlpha: 0, ease: ease_in}, "+=1") // lineartronic bg image .to("#prop_22", {yPercent: 0, opacity: 1, autoAlpha: 1}, "lineartronic_img") .to("#prop_23", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.5") .to("#prop_24", {opacity: 1, autoAlpha: 1, yPercent: 0}, "-=0.25") .fromTo("#prop_23", {opacity: 1, autoAlpha: 1, yPercent: 0, ease: ease_in}, {opacity: 0, autoAlpha: 0, yPercent: -100}, "+=0.5") .fromTo("#prop_24", {opacity: 1, autoAlpha: 1, yPercent: 0, ease: ease_in}, {opacity: 0, autoAlpha: 0, yPercent: -100}, "-=0.25") .fromTo("#prop_22", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, { yPercent: -50, opacity: 0, autoAlpha: 0}, "-=0.67") // SI-Drive .add("si_drive") // steering_wheel .to("#prop_25", {yPercent: mobile ? -50 : 0, opacity: 1, autoAlpha: 1, ease: expo_out}) .fromTo("#prop_25", {scale: 1, xPercent: "-=0", yPercent: mobile ? -50 : 0, ease: expo_in_out}, {scale: mobile ? 0.7 : 3, xPercent: mobile ? "-=0" : "-=60", yPercent: mobile ? -73 : -33}) .to(mobile ? "#prop_28" : "#prop_27", {yPercent: 0, opacity: 1, autoAlpha: 1}) .to(mobile ? "#prop_27" : "#prop_28", {yPercent: 0, opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo(mobile ? "#prop_28" : "#prop_27", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "+=0.5") .fromTo(mobile ? "#prop_27" : "#prop_28", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "-=0.25") .to("#prop_33", {fill: '#DA9320'}) .to(mobile ? "#prop_30" : "#prop_29", {yPercent: 0, opacity: 1, autoAlpha: 1}, "-=0.67") .to(mobile ? "#prop_29" : "#prop_30", {yPercent: 0, opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo(mobile ? "#prop_30" : "#prop_29", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "+=0.5") .fromTo(mobile ? "#prop_29" : "#prop_30", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "-=0.25") .to(mobile ? "#prop_32" : "#prop_31", {yPercent: 0, opacity: 1, autoAlpha: 1}) .to(mobile ? "#prop_31" : "#prop_32", {yPercent: 0, opacity: 1, autoAlpha: 1}, "-=0.25") .fromTo(mobile ? "#prop_32" : "#prop_31", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "+=0.5") .fromTo(mobile ? "#prop_31" : "#prop_32", {yPercent: 0, opacity: 1, autoAlpha: 1, ease: ease_in}, {yPercent: -100, opacity: 0, autoAlpha: 0}, "-=0.1") .fromTo("#prop_25", {yPercent: mobile ? -73 : -33, ease: expo_in}, {yPercent: -183, opacity: 0, autoAlpha: 0}, "-=0.67"); }, attachEvents: () => { window.addEventListener('resize', _a.handleResize, false); }, handleResize: () => { ScrollTrigger.refresh(); } }; window.addEventListener('load', _a.init, false); })(); Link to comment Share on other sites More sharing options...
Cassie Posted May 13, 2022 Share Posted May 13, 2022 I'll dig into this in a bit, but just a tip from a quick glance. You can use matchMedia to handle timelines on different devices.https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.matchMedia() 1 Link to comment Share on other sites More sharing options...
delivous Posted May 13, 2022 Author Share Posted May 13, 2022 Hey @Cassie, Thank you again for your response! I'll try to implement that. Link to comment Share on other sites More sharing options...
OSUblake Posted May 13, 2022 Share Posted May 13, 2022 And you don't need those resize and load event listeners as ScrollTrigger automatically does that. 1 Link to comment Share on other sites More sharing options...
GreenSock Posted May 13, 2022 Share Posted May 13, 2022 6 hours ago, delivous said: Again, as I'm not able to reproduce this issue on codepen, I'm attaching a minimal demo of how I'm structuring the timelines as well the updated live project(https://delivious.000webhostapp.com/safety-tech.php). You said you were attaching a minimal demo. Did I miss it? I see a CodePen (which you said works fine)...and a link to a live site...where's the minimal demo that allows us to see the issue in context? It's virtually impossible to troubleshoot blind. Is there some way you can create a separate minimal demo with just some colored <div> elements that reliably reproduces the issue and send that to us? 1 Link to comment Share on other sites More sharing options...
delivous Posted May 14, 2022 Author Share Posted May 14, 2022 13 hours ago, GreenSock said: Is there some way you can create a separate minimal demo with just some colored <div> elements that reliably reproduces the issue and send that to us? I tried reproducing the issue for a minimal demo, but again I couldn't as gsap had nothing to do with this issue. I'm really sorry for wasting your guys' time. It turns out the issue was coming from the owl carousel that was sometimes being loaded before or after the GSAP code. I know, I feel really stupid for not noticing this sooner. I've combined the code to a single load event handler and now it's fixed! Thank you all for your time and @GreenSock thank you for making GSAP public! It's truly amazing! 2 Link to comment Share on other sites More sharing options...
delivous Posted May 14, 2022 Author Share Posted May 14, 2022 17 hours ago, OSUblake said: And you don't need those resize and load event listeners as ScrollTrigger automatically does that. Thank you, I've removed them. 1 Link to comment Share on other sites More sharing options...
GreenSock Posted May 14, 2022 Share Posted May 14, 2022 7 hours ago, delivous said: It turns out the issue was coming from the owl carousel that was sometimes being loaded before or after the GSAP code. I know, I feel really stupid for not noticing this sooner. I've combined the code to a single load event handler and now it's fixed! Thank you all for your time and @GreenSock thank you for making GSAP public! It's truly amazing! Glad you figured it out! No need to feel stupid - we've all done stuff like that before. It's the nature of development sometimes. Happy tweening! 1 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