Jump to content
Search Community

ScrollTrigger: Weird behaviour at the endpoint

delivous test
Moderator Tag

Recommended Posts

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

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

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!

  • Like 1
Link to comment
Share on other sites

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

  • Thanks 1
Link to comment
Share on other sites

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

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

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? 

  • Like 1
Link to comment
Share on other sites

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!

  • Like 2
Link to comment
Share on other sites

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!

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