Jump to content
Search Community

Add scrollTrigger timeline into matchMedia() functions

DeltaFrog test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Howdy yall,

 

I'm trying to add a matchMedia() function to my code but when I move the tl into the function it seems to breaks the js.   My goal is to be able to setup different trigger start values for mobile devices.   What am I doing wrong here?  :D


This is the current state of the code:  

 

 
gsap.registerPlugin(ScrollTrigger);


ScrollTrigger.matchMedia({
    
  // large
  "(min-width: 960px)": function() {
    // setup animations and ScrollTriggers for screens 960px wide or greater...
    // These ScrollTriggers will be reverted/killed when the media query doesn't match anymore.

  },

  // medium
  "(min-width: 600px) and (max-width: 959px)": function() {
    // The ScrollTriggers created inside these functions are segregated and get
    // reverted/killed when the media query doesn't match anymore. 
  },

  // small
  "(max-width: 599px)": function() {
    // The ScrollTriggers created inside these functions are segregated and get
    // reverted/killed when the media query doesn't match anymore. 
  },
    
  // all 
  "all": function() {
    // ScrollTriggers created here aren't associated with a particular media query,
    // so they persist.
  }
    
}); 





let tl = gsap.timeline({
  scrollTrigger: {
    trigger: ".chartsContainer",
    start: "top 25%",    // [trigger] [scroller] positions
    end: "3000px 3%", // [trigger] [scroller] positions
    markers: "true", // only during development!
    scrub: 1,

    //onUpdate: (self) => console.log(self.progress.toFixed(2)),
    
    snap: {
      snapTo: [0.00, 0.20, 0.40, 0.60, 0.80, 1.00,],
      duration: 0.01,
      ease: "strong"
    },

    pin: "#wrap"  //  "body" or just "true" no quotes  // or selector or element to pin
  
  }
  
});




tl.timeScale(3)



tl.from(".chart1", {scale: 0, duration: 1})

tl.to(".chart1", {autoAlpha: 1, duration: 1},"<") // "<" align start of tween with previous tween

tl.to("#btn1 > div > a", {color: "#9365F0", duration: .2},"<") 

tl.to(".chart1", {autoAlpha: 1, duration: 1},"<")  

// SNAP 1

tl.to(".chart1", {autoAlpha: 0, duration: 1})

tl.to(".chart2", {autoAlpha: 1, duration: 1},"<") 

tl.to("#descriptionID_1", {autoAlpha: 0, duration: 1 },"<")  

tl.to("#headingID_1", {autoAlpha: 0, duration: 1},"<")

tl.to("#headingID_2", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_2", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn1 > div > a", {color: "white", duration: .2},"<")  

tl.to("#btn2 > div > a", {color: "#9365F0", duration: .2},"<")  

// SNAP 2

tl.to(".chart2", {autoAlpha: 0, duration: 1})

tl.to("#headingID_2", {autoAlpha: 0, duration: 1},"<")

tl.to("#descriptionID_2", {autoAlpha: 0, duration: 1},"<")

tl.to(".chart3", {autoAlpha: 1, duration: 1},"<")

tl.to("#headingID_3", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_3", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn2 > div > a", {color: "white", duration: .2},"<")

tl.to("#btn3 > div > a", {color: "#9365F0", duration: .2},"<")


// SNAP 3


tl.to(".chart3", {autoAlpha: 0, duration: 1})

tl.to("#descriptionID_3", {autoAlpha: 0, duration: 1},"<")

tl.to("#headingID_3", {autoAlpha: 0, duration: 1},"<")

tl.to(".chart4", {autoAlpha: 1, duration: 1},"<")

tl.to("#headingID_4", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_4", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn3 > div > a", {color: "white", duration: .2},"<")

tl.to("#btn4 > div > a", {color: "#9365F0", duration: .2},"<")

tl.to(".chart4", {scale: 0, duration: 1})

tl.to(".chart4", {autoAlpha: 0, duration: 1},"<") 

tl.to("#btn4 > div > a", {color: "white", duration: 1},"<")




 

 

 

Here is what I tried:

 

 
gsap.registerPlugin(ScrollTrigger);


ScrollTrigger.matchMedia({
    
  // large
  "(min-width: 960px)": function() {
    // setup animations and ScrollTriggers for screens 960px wide or greater...
    // These ScrollTriggers will be reverted/killed when the media query doesn't match anymore.


let tl = gsap.timeline({
  scrollTrigger: {
    trigger: ".chartsContainer",
    start: "top 25%",    // [trigger] [scroller] positions
    end: "3000px 3%", // [trigger] [scroller] positions
    markers: "true", // only during development!
    scrub: 1,

    //onUpdate: (self) => console.log(self.progress.toFixed(2)),
    
    snap: {
      snapTo: [0.00, 0.20, 0.40, 0.60, 0.80, 1.00,],
      duration: 0.01,
      ease: "strong"
    },

    pin: "#wrap"  //  "body" or just "true" no quotes  // or selector or element to pin
  
  }
  
});






  },

  // medium
  "(min-width: 600px) and (max-width: 959px)": function() {
    // The ScrollTriggers created inside these functions are segregated and get
    // reverted/killed when the media query doesn't match anymore. 
  },

  // small
  "(max-width: 599px)": function() {
    // The ScrollTriggers created inside these functions are segregated and get
    // reverted/killed when the media query doesn't match anymore. 
  },
    
  // all 
  "all": function() {
    // ScrollTriggers created here aren't associated with a particular media query,
    // so they persist.

    

tl.timeScale(3)



tl.from(".chart1", {scale: 0, duration: 1})

tl.to(".chart1", {autoAlpha: 1, duration: 1},"<") // "<" align start of tween with previous tween

tl.to("#btn1 > div > a", {color: "#9365F0", duration: .2},"<") 

tl.to(".chart1", {autoAlpha: 1, duration: 1},"<")  

// SNAP 1

tl.to(".chart1", {autoAlpha: 0, duration: 1})

tl.to(".chart2", {autoAlpha: 1, duration: 1},"<") 

tl.to("#descriptionID_1", {autoAlpha: 0, duration: 1 },"<")  

tl.to("#headingID_1", {autoAlpha: 0, duration: 1},"<")

tl.to("#headingID_2", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_2", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn1 > div > a", {color: "white", duration: .2},"<")  

tl.to("#btn2 > div > a", {color: "#9365F0", duration: .2},"<")  

// SNAP 2

tl.to(".chart2", {autoAlpha: 0, duration: 1})

tl.to("#headingID_2", {autoAlpha: 0, duration: 1},"<")

tl.to("#descriptionID_2", {autoAlpha: 0, duration: 1},"<")

tl.to(".chart3", {autoAlpha: 1, duration: 1},"<")

tl.to("#headingID_3", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_3", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn2 > div > a", {color: "white", duration: .2},"<")

tl.to("#btn3 > div > a", {color: "#9365F0", duration: .2},"<")


// SNAP 3


tl.to(".chart3", {autoAlpha: 0, duration: 1})

tl.to("#descriptionID_3", {autoAlpha: 0, duration: 1},"<")

tl.to("#headingID_3", {autoAlpha: 0, duration: 1},"<")

tl.to(".chart4", {autoAlpha: 1, duration: 1},"<")

tl.to("#headingID_4", {autoAlpha: 1, duration: 1},"<")

tl.to("#descriptionID_4", {autoAlpha: 1, duration: 1},"<")

tl.to("#btn3 > div > a", {color: "white", duration: .2},"<")

tl.to("#btn4 > div > a", {color: "#9365F0", duration: .2},"<")

tl.to(".chart4", {scale: 0, duration: 1})

tl.to(".chart4", {autoAlpha: 0, duration: 1},"<") 

tl.to("#btn4 > div > a", {color: "white", duration: 1},"<")


  }
    
}); 

:D 

 

 

 

Link to comment
Share on other sites

  • Solution

That's because you declared your "tl" variable INSIDE one of the matchMedia() functions, thus it's local and it won't be available outside that function. It has nothing to do with GSAP - that's just how JavaScript works. 

 

But it's not a good idea to have all that code outside the matchMedia() anyway - remember that those functions will get called every time it matches, so if a user resizes their viewport it may cross a threshold and call one of those. When it no longer matches one, it kills the ScrollTriggers that were created inside it. So your code is creating the timeline in there but you're populating it only ONCE outside the matchMedia(), thus it'll work fine the first time but then if you resize and come back, it won't work anymore because it'll fire that function, create a timeline...and not populate it. 

 

If most of the code is the same but you have a few things different, you can just create a function and parameterize it. 

 

crollTrigger.matchMedia({
    
  // large
  "(min-width: 960px)": function() {
    buildTimeline("large");
  },

  // medium
  "(min-width: 600px) and (max-width: 959px)": function() {
    buildTimeline("medium");
  },

  // small
  "(max-width: 599px)": function() {
    buildTimeline("small");
  }
    
}); 


function buildTimeline(size) {
  let tl = gsap.timeline({
    scrollTrigger: { ... }
  });
  tl.to("#id", {
    x: size === "large" ? 500 : -100, // conditional logic based on size
    ...
  });
}

I hope that helps.

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