Jump to content
Search Community

Recommended Posts

Posted

Hi everyone,

 

I’m encountering an issue with GSAP’s ScrollTrigger where a section jumps when unpinning, and I’m looking for some guidance or a solution.

 

Problem:

I have a section that is pinned using ScrollTrigger while scrolling, but when the pinning ends (unpins), the section seems to "jump" or shift unexpectedly.

The behavior happens when the scroll reaches the end point defined in the ScrollTrigger. I am also using scrub for smooth scrolling, and pinSpacing: false to prevent extra space for the pinned element.  May refer to the section via https://cantal.bluecube.com.sg/sectors/

 

Here attached the CSS that I used:

.scrolling-cards {
    overflow: hidden !important;
    position: relative !important;
}

.scrolling-cards-header-wrapper {
    height: 100vh !important;
    left: 0;
    position: relative !important;
    top: 0;
    width: 100% !important;
}

.scrolling-cards-header {
    height: 100vh;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}

.scrolling-cards-image {
    height: 100vh !important;
    left: 0;
    position: absolute !important;
    top: 0;
    width: 100% !important;
}

.scrolling-cards-image:after {
    background: #000;
    content: "";
    height: 100%;
    left: 0;
    opacity: .3;
    position: absolute;
    top: 0;
    width: 100%;
}

.scrolling-cards-image img {
    height: 100vh !important;
    object-fit: cover !important;
}

.scrolling-cards-title {
    position: fixed !important;
    top: 0;
    left: 0;
    width: 50% !important;
    height: 100vh !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 50px !important;
    z-index: 10 !important;
}

.scrolling-cards-item {
    height: 100vh !important;
    position: relative !important;
    width: 100% !important;
}

.scrolling-cards-card {
    background-color: #FFF;
    padding: 50px !important;
    position: absolute !important;
    right: 50% !important;;
    top: 50% !important;
    transform: translateX(50%);
    width: 580px !important;
    z-index: 2 !important;
}

.scrolling-cards-card p:last-child {
    margin-bottom: 0;
}

@media screen and (min-width: 1024px) {
    .scrolling-cards-title {
        justify-content: center !important;
        padding: 0 0 0 calc((100vw - 1180px) / 2 + 20px) !important;
        width: 48vw !important;
    }

    .scrolling-cards-card {
        max-width: calc(50% - 20px);
        right: calc((100vw - 1180px) / 2 - 20px) !important;
        /* top: 250px !important; */
        transform: translateY(-50%);
    }
}

@media screen and (max-width: 1024px) {
    .scrolling-cards-title {
        width: 100% !important;
        justify-content: unset !important;
        padding-left: 23px !important;
        padding-right: 23px !important;
    }

    .scrolling-cards-card {
        left: 50% !important;
        right: auto !important;
        transform: translate(-50%, -50%) !important;
        width: calc(100vw - 46px) !important;
        padding: 30px 25px !important;
    }

}

 

And here is the gsap script that I used:

document.addEventListener("DOMContentLoaded", function () {
    gsap.registerPlugin(ScrollTrigger);

    const cards = gsap.utils.toArray(".scrolling-cards-item");
    const images = gsap.utils.toArray(".scrolling-cards-image");

    if (cards.length > 1 && !document.body.classList.contains("wp-admin")) {
        const tl = gsap.timeline({
            scrollTrigger: {
                trigger: ".scrolling-cards",
                pin: ".scrolling-cards-header",
                start: "top top",
                end: "bottom bottom",
                scrub: 1,
                anticipatePin: 1,
                pinSpacing: false,
                markers: true
            }
        });

        cards.forEach((cardWrapper, i) => {
            const card = cardWrapper.querySelector(".scrolling-cards-card");
            const image = images[i];
            const prevCard = i > 0 ? cards[i - 1].querySelector(".scrolling-cards-card") : null;

            const baseTime = i * 1.5 ;

            // Fade in background image (if not the first)
            if (i!==0) {
                tl.from(image, {
                    autoAlpha: 0,
                    duration: 1
                }, baseTime);
            }   

            // Fade in card
            // if (i !== 0) {
                tl.from(card, {
                    autoAlpha: 0,
                    y: 60,
                    duration: 0.5
                }, baseTime + 0.5);
            // }

            // Fade out previous card (if not the first)
            if (i > 0 && prevCard) {
                tl.to(prevCard, {
                    autoAlpha: 0,
                    y: -60,
                    duration: 0.5
                }, baseTime);
            }

        });
    }
});

 

The Issue:

When the scroll reaches the end of the ScrollTrigger, the section "jumps" or shifts suddenly as the pin is released. I suspect this might be related to the CSS positioning (position: fixed on .scrolling-cards-title) and overflow: hidden on the parent .scrolling-cards.

 

What I’ve Tried:

I’ve tried adjusting the pinSpacing setting (true and false), but the jump still happens.

Removing the overflow: hidden style from .scrolling-cards does not resolve the issue either.

The jump seems to occur at the end of the ScrollTrigger, right before the element unpins.

GSAP Helper
Posted

Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependencies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen.

that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import GSAP as shown in the Install Helper in our Learning Center : 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

mvaneijgen
Posted

Hi @Jia welcome to the forum!

 

Sadly we can't debug a live website, there is just no way to edit the code.

 

I also work in Wordpress, but personally I always start with all my animations on a place like Codepen, just to test my animation in its basic form with pure HTML, CSS and JS to make sure my animation is working as expected and not my framework or in this case platform is trowing errors. This also makes it really easy to debug, because you have a known working version and next to that you can easily share a version on places like this to ask for feedback when you get stuck.
 

pinSpacing is needed for pinning to work in ScrollTrigger and you can't use position: fixed (or sticky) in pinned ScrollTriggers. It is hard to judge how your setup is working now but I have the feeling you're leveraging scroll instead of using animations which will make things much easier. 

 

Check out my post on how to create a stacking card effect which is not what you're looking for, but the starting point where everything starts out stacked on top of each other and then instead of scrolling you move things on the y-axis which will give you the illusion of scrolling will make it that everything will work a lot beter and easier to manage.

 

Quote

 

The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging.  
  
Most of the ScrollTrigger effects you see are just moving things on the y-axis instead of scrolling them, then hooking that animation to ScrollTrigger will give the illusion of scrolling, but they are really just animating! Getting to grips with this knowledge will make it so much easier to create all kinds of effects, I've written a whole post about it, check it out:

 

 

 

 

Hope it helps and happy tweening! 

 

Posted


Hello there, @Jia

Your problem looks like it is most likely related to transitions applied via CSS on the pinning element/s, thus conflicting with how ScrollTrigger handles things.

Unbenannt.thumb.png.68dc81f6dfedfad21fae46722c499199.png
From a quick glance, just removing the transform-transition already got rid of any jumping I could see at the end of that section - no guarantee though, that this is all you have to keep an eye on. From what I know, Elementor by default sets lots of 'transition: all' on elements. Check on the older thread linked below. 

You might also have added some custom transitions to those elements on top of that yourself, so what you're going to want to do is remove any transitions of properties on elements that might interfere with what ScrollTrigger is doing - or if they are set by Elementor, overwrite them in some way.


I hope this can be of help. Good luck with your project.
 

 

  • Like 1

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