Jump to content
Search Community

ScrollTrigger element goes out of viewport if page is refreshed during timeline

Jakob3 test
Moderator Tag

Recommended Posts

Hey!

 

I only recently started experimenting with gsap and so far i really love it.

 

I'm making a website with scrolltrigger animations, basically a svg path that is 100% height and width with position fixed and it's being animated on scroll (background effect). I have 4 sections and each section will trigger a transition animation.

 

On initial page load, the animation plays out well. But, If I refresh the page somewhere in the middle it will sometime load correctly and other times it will mess up positioning (instead of going 200px right it goes completely off screen).

 

Any idea what could be the issue? Am I not using scroll trigger correctly?

 

//SVG's path that's being animated
<svg
    height="100%"
    width="100%"
    viewBox="0 0 1000 700"
    preserveAspectRatio="none"
    class="{className} {blobClass}"
>
    <path height="100%" width="100%" d="" fill="#eff0fd" />
</svg>


//Callback to function that loops a svg animation
let tl = gsap.timeline({
            onUpdate: function () {
                animate();
            },
            repeat: -1
        });



        //animate transition to section 2

        let blobTl02 = gsap.timeline({
            scrollTrigger: {
                trigger: '.section-02',
                start: 'top bottom',
                scrub: 1.5,
                end: 'bottom bottom'
                // markers: true
            },
            onComplete: function () {
                tl.pause();
            },
            onReverseComplete: function () {
                tl.play();
            }
        });
  
        blobTl02.set(`.${blobClass} path`, { transformOrigin: 'center center' });
        blobTl02.to(
            `.${blobClass} path`,
            {
                // scale: '5',
                // translateX: '-200px',
                translateY: '-350px',
                ease: 'Power1.inOut'
            },
            'transition'
        );
        blobTl02.to(
            `.${blobClass} path`,
            {
                scale: '6.5',
                fill: '#faf9ff',
                ease: 'Power1.inOut',
                delay: '0.1'
            },
            'transition'
        );
  
        //Animate to section 3
  
        let blobTl03 = gsap.timeline({
            scrollTrigger: {
                trigger: '.section-03',
                start: 'top bottom',
                scrub: 1.5,
                end: 'bottom bottom'
                // markers: true
            },
            onComplete: function () {
                tl.play();
            },
            onReverseComplete: function () {
                tl.pause();
            }
        });
  
        blobTl03
            .to(
                `.${blobClass} path`,
                {
                    // scale: '5',
                    // translateX: '-200px',
                    translateY: 50,
                    translateX: -430,
                    ease: 'Power1.inOut'
                },
                'transition'
            )
            .to(
                `.${blobClass} path`,
                {
                    scale: 1,
                    fill: '#faf9ff',
                    ease: 'Power1.inOut',
                    delay: '0.1'
                },
                'transition'
            );
  
        //Animate to section 4
  
        let blobTl04 = gsap.timeline({
            scrollTrigger: {
                trigger: '.section-04',
                start: 'top bottom',
                scrub: 1.5,
                end: 'bottom bottom'
                // markers: true
            },
            onComplete: function () {
                tl.pause();
            },
            onReverseComplete: function () {
                tl.play();
            }
        });
  
        blobTl04
            .to(
                `.${blobClass} path`,
                {
                    scale: 5.5,
                    fill: '#faf9ff',
                    ease: 'Power1.inOut',
                    delay: '0.1'
                },
                'transition'
            );
Link to comment
Share on other sites

Maybe an important info is that I'm using SvelteKit. On mounting I do a scrolltrigger.refresh and on destroy as well.

 

Here is a video of the behavior (first scroll is correct, after refresh is incorrect):

 

If I console.log the SVG path's bounding box it's like this:

- On a normal load it will get correct dimensions and position

DOMRect {x: 972.82568359375, y: 230.93328857421875, width: 750.803955078125, height: 586.3333129882812, top: 230.93328857421875, …}

- If I scroll up and down while reloading or sometimes if I reload in the middle of the page it will get positions and size as 0

DOMRect {x: 0, y: 0, width: 0, height: 0, top: 0, …}

 

 

 

Link to comment
Share on other sites

Heya!

This definitely sounds like something funny going on with sveltekits lifecycle events rather than GSAP

 

3 hours ago, Jakob3 said:

If I console.log the SVG path's bounding box it's like this:

- On a normal load it will get correct dimensions and position

DOMRect {x: 972.82568359375, y: 230.93328857421875, width: 750.803955078125, height: 586.3333129882812, top: 230.93328857421875, …}

- If I scroll up and down while reloading or sometimes if I reload in the middle of the page it will get positions and size as 0

DOMRect {x: 0, y: 0, width: 0, height: 0, top: 0, …}


Have you tried taking it over to the svelte forums to find out why you're getting different values?

https://github.com/sveltejs/kit/discussions

Link to comment
Share on other sites

50 minutes ago, Cassie said:

Heya!

This definitely sounds like something funny going on with sveltekits lifecycle events rather than GSAP

 


Have you tried taking it over to the svelte forums to find out why you're getting different values?

https://github.com/sveltejs/kit/discussions

Hey! Thanks for pointing me in that direction :)

I did one more test and put the SVG in a div wrapper and animated that div in same way. In this case the issue is not happening. Perhaps it does have something to do with gsap?

 

I'd create a codepen demo but this issue is not possible to recreate there, I tried.

Link to comment
Share on other sites

1 hour ago, Cassie said:

Have you tried making a demo over on codesandbox?

 

I'm afraid we can't really help without actually seeing the issue.

 

I've tried it and I also can't reproduce it there. Probably because it re-builds the code when refreshing/running code, it doesn't behave the same as regular page refresh?

 

I attached a very slim example that reproduces this issue, I hope this is allowed :)

 

To install just run npm install and then npm run dev

demo.zip

Link to comment
Share on other sites

Hi Jakob,

 

I can't reproduce the issue from your demo, so there's not a lot we can really advise. If the client rect is showing 0, that's probably not a GSAP issue. Sounds like you need to call your animate function right after creating your points and noise.

 

The only other I can suggest is that you are animating some of the same blobs properties in 2 different timeline, like x and y in your 2nd and 3rd timeline. That might be creating conflict, so it would probably better to animate a wrapper element, like a <g> element around your path so they will never conflict.

 

Good luck!

 

Link to comment
Share on other sites

On 2/1/2022 at 7:15 AM, OSUblake said:

Hi Jakob,

 

I can't reproduce the issue from your demo, so there's not a lot we can really advise. If the client rect is showing 0, that's probably not a GSAP issue. Sounds like you need to call your animate function right after creating your points and noise.

 

The only other I can suggest is that you are animating some of the same blobs properties in 2 different timeline, like x and y in your 2nd and 3rd timeline. That might be creating conflict, so it would probably better to animate a wrapper element, like a <g> element around your path so they will never conflict.

 

Good luck!

 

Hello Blake,

 

Thank you for taking a look. Tried all of the above but the only way to avoid this was to animate a div wrapper around svg.

 

Would perhaps this animation be better suited for canvas instead of svg?

 

Many thanks

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