Jump to content
Search Community

Nuxt GSAP ScrollTrigger possible conflict import w multiple components

pdub test
Moderator Tag

Recommended Posts

I am using the npm package for nuxt:

https://www.npmjs.com/package/nuxt-gsap

 

It works alright - I do seem to have to re-register ScrollTrigger on every script tag ( perhaps making a new instance and rewriting the other ).

( i know it is global - but in order to get it working, it seems to have to be registered again for reference sake ).

 

Regardless, working alright - except when in this instance I need to add a series of timeline animations to the utils array contained within a component.

A nuxt component's lifecycle fires mounted() when the DOM element has been added...and when I added it without the below code, it completely broke - and my guess is that there was multiple instances?? of either a timeline or multiple instances of gsap ( i'm not even sure at this point ) that was competing with one another.

 

Since I have multiple components, I wrote kind of a 'hack' to see if it's the first instance ( using an id generated by index ) of this component, and if it is, only create a timeline instance with a forEach array of my classes I need to animate. It looks to be working, for now, but I'm pretty confident that once live, there will be times where this component renders before the others and thus doesn't apply the forEach loop to the other classes ( b/c they aren't rendered yet ). Can someone talk me off a ledge and say it'll be OK ( because of the way gsap works? ) or suggest a different solution. I know it's a tough case ( and also partly/mostly a nuxt question ) - thanks:

 

<!-- parent component, pass index/id -->
<template>
			<section>
				<FeaturedSection v-for="(item,index) in mycontent" :id="index" :key="item._uid"/>
			</section>
</template>


<! -- FeaturedSection/child component - say I have 3 of these, but each one fires mounted I think -->
<template>
		<section>
		    <component v-for="mycomponent in mycontent" class="feat-component" :key="mycomponent._uid" :blok="mycomponent" :is="mycomponent.component" :id="id"></component>
		</section>

</template>

<script>
	import { ScrollTrigger } from "gsap/dist/ScrollTrigger.js";
	export default {
		mounted(){
			let st = this.$gsap.registerPlugin(ScrollTrigger);
			let gsp = this.$gsap;
		  	gsp.utils.toArray(".feat-component").forEach((blk,index) => {

				if(this.id==0 && index != 0){
			  		let tl = this.$gsap.timeline({
			  			scrollTrigger: {
			  				trigger: blk,
			  				markers: true,
			  				scrub:true
			  			}
			  		});
			  		tl.from(blk, {
			  			duration: 2,
			  			y:"+600",
			  			ease: "expo.out"
			  		});
				}
		  	});
		}
	}
</script>

 

 

 

 

 

Link to comment
Share on other sites

Adding to this before any answer and just in case no one answers but someone is searching for a 'solve'/hack:

 

My parent won't call mounted() until it's children are all mounted.

So I set a prop on the child called parentmounted ( heyo ) - which when mounted() in parent is called, I set from false ( in the data() ) to true.

//parent
mounted() {
            console.log("ALL FEATURED WORK IS MOUNTED")
            this.fullyMounted = true;

 

So now my components are all loaded, I set a watch for the prop change them, and if it's the first instance, i'll create the forEach looking for all the rendered classes.

watch: {
              parentmounted: function(newVal, oldVal) { // watch it
                  // hack way of determining that the parent has loaded then only create one instance/one timeline of gsap
                let st = this.$gsap.registerPlugin(ScrollTrigger);
                let gsp = this.$gsap;
                  gsp.utils.toArray(".feat-component").forEach((blk,index) => {
                    if(this.id==0 && index != 0){
                          let tl = this.$gsap.timeline({
                              scrollTrigger: {
                                  trigger: blk,
                                  markers: true,
                                  scrub:true
                              }
                          });
                          tl.from(blk, {
                              duration: 2,
                              y:"+400",
                              ease: "expo.out"
                          });
                    }
                  });
            }
        }

 

There is probably a better way to do it - but at least this way I know that all my '.feat-component' DOM el's will be loaded.

And I set only one global timeline ( i'm not so sure if it's the timeline object, the global gsap object, or the utils array that was f'ing everything up ).

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