Jump to content
Search Community

Weird behaviour of ScrollTrigger in svelte and markers are missing and/or appear when changing zoom

Lightning

Go to solution Solved by mvaneijgen,

Recommended Posts

Posted

Below I have a small sveltekit demo to see how the scrollTrigger works in gsap.

 

So basically I have 2 divs which both have a height of h-screen. The first div was just me trying out an animation on a box so you can ignore that. The second div has a <h1> tag with a classname of "myText" and the text says "This is some text". Now I to move this text a 1000 pixels horizontally using gsap using a scrolltrigger i.e when it enters the viewport.

 

But for some reason it doesn't work and when I use the markers it doesn't even show up on the text.

 

image.thumb.png.71bd8f9956c97c3f4384e0d6d8a2d4b7.png

 

And here is the code:

<script lang="ts">
	import { onMount } from "svelte";
    import gsap from "gsap";
    import { Flip } from "gsap/dist/Flip";
    import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
    import { rotateBox } from "$lib/animUtils";
    
    onMount(() => {
        gsap.registerPlugin(ScrollTrigger);
        gsap.registerPlugin(Flip);
        const state = Flip.getState(".myBox");
        rotateBox(state);
        gsap.to(".myText", {
            scrollTrigger: {
                trigger: ".myText",
                start: "top center",
                markers: true,
                toggleActions: "restart none none none",
            },
            x:1000,
            duration: 2,

        });

    });


</script>

<main class="h-screen flex flex-col overflow-x-hidden">
    <div class="min-h-full flex flex-col items-center justify-center">
        <h1 class="text-xl">
            This is some text
        </h1>
        <div class="myBox box-content h-32 w-32 bg-purple-950 rounded-lg">
            
        </div>
    </div>
    <div class="min-h-full flex flex-col items-center justify-center">
        <h1 class="myText text-8xl border-2 border-black">
            This is some text
        </h1>
    </div>
</main>

 

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? 

 

Side note: You should never animate your trigger element, just wrap it in an extra div and use that as the trigger element!

 

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 the gsap-trial NPM package for using any of the bonus plugins: 

 

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. 

Posted

Hi @Lightning and welcome to the GSAP Forums!

 

Besides our Svelte and SvelteKit collections on Stackblitz you can create a Repl directly on Svelte if you want, here is a starter that has GSAP and ScrollTrigger:

https://svelte.dev/playground/9472eb02a4bd4080a05d6d3c4d23d81d?version=5.1.6

 

Also is worth noticing that you have two vertical scroll bars in your app (based on the image you posted). This seems to stem from the class h-screen you have in your <main> tag, which gives that element a height of 100vh. Basically you have scrolling on the body tag and inside that element as well, but based on the configuration you're passing to ScrollTrigger you're using the default scroller which is the body tag.

 

My recommendation, on top of creating a minimal demo, is to just remove that class from the <main> tag and see how that works.

 

Hopefully this helps

Happy Tweening!

  • Solution
Posted

If you place your whole timeline + ScrollTrigger logic to the onMounted component everything works as expect. In the onMounted you're sure that alle elements are loaded and thus ScrollTrigger has acces to the .this element. This is also stated in the console Element not found: .this

 

I also changed your .fromTo() to a .from() no need the specify a .to() if the values you tween to are the default values of the browser and also changed your x to a xPercent check out https://gsap.com/resources/mistakes/ 

 

Hope it helps and happy tweening! 

 

https://svelte.dev/playground/fa60cdf733d044b98151cae523793a66?version=5.1.6

  • Like 1
Posted
2 hours ago, mvaneijgen said:

If you place your whole timeline + ScrollTrigger logic to the onMounted component everything works as expect. In the onMounted you're sure that alle elements are loaded and thus ScrollTrigger has acces to the .this element. This is also stated in the console Element not found: .this

 

I also changed your .fromTo() to a .from() no need the specify a .to() if the values you tween to are the default values of the browser and also changed your x to a xPercent check out https://gsap.com/resources/mistakes/ 

 

Hope it helps and happy tweening! 

 

https://svelte.dev/playground/fa60cdf733d044b98151cae523793a66?version=5.1.6

It works now thank you so much! I still don't exactly know why doing this fixed it so could you please explain further?

Posted
24 minutes ago, Lightning said:

I still don't exactly know why doing this fixed

It is just a guess, but I think the elements are not ready (loaded) when the code executes, so waiting for onMount (this is probably the life cycle hook that fires after the component has loaded, at least this is how it works in Vue.js. I've never worked with Svelte, fyi!), so if you're not familiar with these life cycle hooks in Svelte I highly recommend taking a look at their docs  https://svelte.dev/docs/svelte/lifecycle-hooks 

 

Hope it helps and happy tweening! 

  • Like 2
Posted

Hi,

 

Indeed Mitchel is right, the onMount hook is a way to know that the DOM elements are rendered and that they can be safely referenced in JS. The code outside that hook actually runs before the DOM is rendered, so the elements are not there yet.

 

Finally all our demos use the onMount hook and the returned callback inside in order to do proper cleanup:

import { onMount } from "svelte";
import gsap from "gsap";

let boxesContainer, tl;

const toggleTimeline = () => {
  tl.reversed(!tl.reversed());
};

onMount(() => {
  const ctx = gsap.context((self) => {
    const boxes = self.selector(".box");
    tl = gsap.timeline({ paused: true });
    tl.to(boxes[0], { x: 120, rotation: 360 })
      .to(boxes[1], { x: -120, rotation: -360 }, "<")
      .to(boxes[2], { y: -166 })
      .reverse();
  }, boxesContainer); // <- Scope!

  return () => ctx.revert(); // <- Cleanup!
});

https://stackblitz.com/edit/vitejs-vite-zegpxi?file=src%2FApp.svelte

 

Hopefully this helps

Happy Tweening!

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