Jump to content
Search Community

In Nuxt, when using ScrollTrigger.kill(), how can it run again when page is viewed?

BMateus test
Moderator Tag

Recommended Posts

Hi again.

 

I'm having an issue I can't seem to go around...

 

In Nuxt, I'm using ScrollTrigger.create to pin to specified panels on a index.vue page. All is fine.

When navigating to other pages (with or without ScrollTriger animations), the new page is still running the ScrollTrigger, thus pinning to the index.vue instructions, even though its a totally diferent page.

 

My initial thought was to do 'ScrollTrigger.kill()' on the lifecycle 'beforeDestroy()', which works... until I come back to the index page to see there's no animation anymore...

 

I can't do it in codepen (don't know how to do Nuxt there), but I've prepared a codesandbox.io.

 

https://codesandbox.io/s/unruffled-antonelli-dl8fw

 

In summary:

  • If I don't do ScrollTrigger.kill(), the next pages still run to the current ScrollTrigger animation (next pages become unusable)
  • If I do ScrollTrigger.kill() when the current page is destroyed, the next pages are correct. But when navigating again to the initial one, there's no more animation.

 

Any ideas? 

Link to comment
Share on other sites

10 minutes ago, BMateus said:

My initial thought was to do 'ScrollTrigger.kill()' on the lifecycle 'beforeDestroy()', which works... until I come back to the index page to see there's no animation anymore...

Why not use .disable() instead? Then .enable() it when the index page is navigated back to?

 

Or .kill() and recreate instead.

Link to comment
Share on other sites

I've replaced the .kill() with .disable().

 

beforeDestroy() {
	ScrollTrigger.disable()
}


But Webpack complains stating ScrollTrigger.disable is not a function.

'

Error details: TypeError: gsap_all__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger.disable is not a function

'

Link to comment
Share on other sites

No no, you're trying to call static methods instead of instance methods.

 

You should never call the [undocumented] static ScrollTrigger.kill() method. That literally kills ScrollTrigger completely so nothing will work after you call that. It's by design (for troubleshooting). You should call kill() on the ScrollTrigger INSTANCE that you want to kill :)

 

Like:

let st = ScrollTrigger.create(...);
// then later...
st.kill();

// or if it's in an animation...
let tween = gsap.to(... {scrollTrigger:{...}});
// then later...
tween.scrollTrigger.kill();

// or use an id:
ScrollTrigger.create({ 
  ...
  id: "my-id"
});
// then later...
ScrollTrigger.getById("my-id").kill();

In your last post, you said you did try the getById() technique but you get an error? Are you positive? I wonder if you didn't assign the id to the ScrollTrigger or something. Can you show us how you did that? 

  • Like 2
Link to comment
Share on other sites

🤦‍♂️

 

Makes total sense.

I'm still green with GreenSock :)

 

 

Quote

In your last post, you said you did try the getById() technique but you get an error? Are you positive? I wonder if you didn't assign the id to the ScrollTrigger or something. Can you show us how you did that? 

Sure, was testing it in real code. Let me update the codesandbox

 

Link to comment
Share on other sites

So, using :

 

mounted() {
    gsap.registerPlugin(ScrollTrigger);

    this.mainAnimation = gsap.timeline();
    ScrollTrigger.enable();

    console.log(this.$refs.panel);

    gsap.utils
      .toArray([this.$refs.paneltop, this.$refs.panel])
      .forEach((eachpanel, i) => {
        console.log("This is panel: ", eachpanel);

        ScrollTrigger.create({
          id: "indexPannels",
          trigger: eachpanel,
          markers: true,
          start: "top top",

          pin: false,
          pinSpacing: false,

          // scrub: 1,
          snap: {
            snapTo: 1,
            duration: {
              min: 0.4,
              max: 0.8
            },
            delay: 0.15,
            anticipatePin: 0.4
          }
        });
      });
  },

  beforeDestroy() {
    ScrollTrigger.getById("indexPannels").disable();
  }

 

Gives me back:

Error details: TypeError: Cannot read property 'disable' of undefined

 

Link to comment
Share on other sites

Ok, managed to get rid of the errors.

 

No, still returns Cannot read property 'disable' of undefined

 

mounted() {
    gsap.registerPlugin(ScrollTrigger);

    this.mainAnimation = gsap.timeline();

    console.log(this.$refs.panel);

    gsap.utils
      .toArray([this.$refs.paneltop, this.$refs.panel])
      .forEach((eachpanel, i) => {
        console.log("This is panel: ", eachpanel);

        ScrollTrigger.create({
          id: "indexPannels",
          trigger: eachpanel,
          markers: true,
          start: "top top",

          pin: false,
          pinSpacing: false,

          // scrub: 1,
          snap: {
            snapTo: 1,
            duration: {
              min: 0.4,
              max: 0.8
            },
            delay: 0.15,
            anticipatePin: 0.4
          }
        });
      });

    ScrollTrigger.getById("indexPannels").enable();
  },

  beforeDestroy() {
    // console.log(ScrollTrigger.getById("indexPannels"));

    ScrollTrigger.getById("indexPannels").disable();
  }

However, Scrolltrigger is not getting disabled on the next pages. Seems its not disabling.

 

 

Link to comment
Share on other sites

Oh, if I do 

 

mounted() {
    gsap.registerPlugin(ScrollTrigger);

    this.mainAnimation = gsap.timeline();

    console.log(this.$refs.panel);

    gsap.utils
      .toArray([this.$refs.paneltop, this.$refs.panel])
      .forEach((eachpanel, i) => {
        console.log("This is panel: ", eachpanel);

        ScrollTrigger.create({
          id: "indexPannels" + i,
          trigger: eachpanel,
          markers: true,
          start: "top top",

          pin: false,
          pinSpacing: false,

          // scrub: 1,
          snap: {
            snapTo: 1,
            duration: {
              min: 0.4,
              max: 0.8
            },
            delay: 0.15,
            anticipatePin: 0.4
          }
        });
      });

    ScrollTrigger.getById("indexPannels0").enable();
    ScrollTrigger.getById("indexPannels1").enable();
    ScrollTrigger.getById("indexPannels2").enable();
    ScrollTrigger.getById("indexPannels3").enable();
  },

  beforeDestroy() {
    console.log(ScrollTrigger.getById("indexPannels0"));
    console.log(ScrollTrigger.getById("indexPannels1"));
    console.log(ScrollTrigger.getById("indexPannels2"));
    console.log(ScrollTrigger.getById("indexPannels3"));

    ScrollTrigger.getById("indexPannels0").disable();
    ScrollTrigger.getById("indexPannels1").disable();
    ScrollTrigger.getById("indexPannels2").disable();
    ScrollTrigger.getById("indexPannels3").disable();
  }

 

I can see the console log of each instance.

 

So it seems i was overwritting the id.

 

It now works. I just need to make a function to make an array of scrolltrigger id's, so I can enable and disable them.

This is because my 'panels' are dynamic, I never know how many there are.

 

UPDATE: Confirmed to be working

 

Link to comment
Share on other sites

Glad you got it working!

 

By the way, if it helps at all, you can use ScrollTrigger.getAll() to get ALL of the ScrollTrigger instances so that you can loop through them and kill() each one if that's easier than managing IDs. But if you need to keep some of them alive for whatever reason, that may not be a good option. 

 

Enjoy!

  • Like 2
Link to comment
Share on other sites

Thank you again. 

.getAll() wouldn't work for my (real) case, as I'm using other anims for menus and stuff.

 

What if (stupid suggestion comming), besides a ScrollTrigger.id, we could have a ScrollTrigger.collection?

Just for these kind of noobs like me that loop through (which actually looks like a regular use case), and wouldn't have to deal with manually churning the id.

It could be an array, and that would made it easier to plug into?

(its probably a dumb idea..., but you never know)

 

Thanks again for the precious help. You rock.

 

 

Link to comment
Share on other sites

Here's an idea for you...

 

Add a "group" (or "collection" if you prefer) to the configuration (vars) object for any of your ScrollTriggers that you want to group. Then use this helper function:

let getScrollTriggerGroup = group => ScrollTrigger.getAll().filter(t => t.vars.group === group);

That way, you could do: 

getScrollTriggerGroup("my-group").forEach(t => t.kill());

Right?

  • Like 3
Link to comment
Share on other sites

Yeah, once ScrollTrigger grabs all the relevant data from the configuration object, it attaches it to the ScrollTrigger instances as a "vars" property (just like animations do). 👍 

 

So yeah, technically you could put whatever you want in there. ScrollTrigger will ignore the stuff it doesn't care about. 

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