jaden Posted August 24, 2020 Share Posted August 24, 2020 I visited scrollTrigger.matchMedia() docs and it's very useful feature I have timeline animation outside of scrollTrigger. I animate 3 elements on mobile and 6 on desktop, and on mobile view there is gap for elements that were set to display: none; with CSS media query whats way around this? PS i'm using interesction observer to run the timeline Link to comment Share on other sites More sharing options...
ZachSaucier Posted August 24, 2020 Share Posted August 24, 2020 Hey jaden. Quote Can we use matchMedia() for timelines outside the scrollTrigger? Try it and see See the Pen OJNWaGz by GreenSock (@GreenSock) on CodePen If you resize the window, you'll see that it will create the animations once the media breakpoint is entered into. However, old effects are never destroyed because there's not a way for GSAP to track what has been created inside of the function. To do this sort of thing, just use the regular JS matchMedia: See the Pen oNxBJXB?editors=0010 by GreenSock (@GreenSock) on CodePen 3 Link to comment Share on other sites More sharing options...
Visual-Q Posted August 24, 2020 Share Posted August 24, 2020 This is a really good pen from @OSUblake Uses matchmedia and has a solution for updating animation as well. Observe how the animation progress is recorded on resize then the animation is cleared out and rebuilt back to the progress that was recorded. See the Pen jLLqbY by osublake (@osublake) on CodePen 7 Link to comment Share on other sites More sharing options...
jaden Posted August 25, 2020 Author Share Posted August 25, 2020 On 8/24/2020 at 5:13 PM, Visual-Q said: This is a really good pen from @OSUblake Uses matchmedia and has a solution for updating animation as well. Observe how the animation progress is recorded on resize then the animation is cleared out and rebuilt back to the progress that was recorded. That looks neat. Thanks for demo. Link to comment Share on other sites More sharing options...
jaden Posted August 25, 2020 Author Share Posted August 25, 2020 On 8/24/2020 at 4:34 PM, ZachSaucier said: Thanks, thats nice example Link to comment Share on other sites More sharing options...
jaden Posted August 27, 2020 Author Share Posted August 27, 2020 On 8/24/2020 at 4:34 PM, ZachSaucier said: To do this sort of thing, just use the regular JS matchMedia: Hi Zack, I been using this and works really well. I have a follow up question tho if you dont mind. I want one tween only to run at mobile and not at all at bigger screens, so I what I did was : if (matches){ gsap.to....) else { return; } Should I use return; or oldAnim.kill(); ? I tried both, and both work just fine, but was wondering what's considered correct way. Actually it works with empty {} aswell. Link to comment Share on other sites More sharing options...
ZachSaucier Posted August 27, 2020 Share Posted August 27, 2020 In general you should kill off an animation if you're done with it so that it can be garbage collected. 1 Link to comment Share on other sites More sharing options...
GreenSock Posted August 28, 2020 Share Posted August 28, 2020 2 hours ago, ZachSaucier said: In general you should kill off an animation if you're done with it so that it can be garbage collected. Just to clarify a little, you do NOT need to worry about killing off every animation you create in order for it to be garbage collected - GSAP automatically releases each animation for GC when it finishes. I think Zach just meant that if your goal is to get rid of animations that haven't finished yet, yes, it'd be good to kill() them. 👍 1 Link to comment Share on other sites More sharing options...
GreenSock Posted August 28, 2020 Share Posted August 28, 2020 One more thing... In 3.5.0, we added the ability to return a function from any of the media queries and that function will get called when the media query no longer matches, so that's the perfect place to put your cleanup code. That also allows you to use ScrollTrigger.matchMedia() for things that aren't ScrollTrigger-related. For example, you could create a bunch of animations in there, assign them to variables, and then in your cleanup function kill() them. Example: ScrollTrigger.matchMedia({ // desktop "(min-width: 800px)": function() { // a timeline that isn't ScrollTrigger-related... let tl = gsap.timeline(); tl.to(".box", {rotation: 360}) .to(".box", {y: 100}); // THIS IS THE KEY! Return a function which will get called when the media query no longer matches so we can kill() the animation (or whatever) return function() { tl.kill(); // other cleanup code can go here... }; } }); https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.matchMedia()#teardown 2 1 Link to comment Share on other sites More sharing options...
pixelpillow Posted September 28, 2021 Share Posted September 28, 2021 This return function is very helpful. I got it working perfectly: See the Pen powKYEM by wildeweg (@wildeweg) on CodePen But when a timeline is defined within a function, I can't get it to work (sorry, this has probably to do with my limited knowledge of javascript.). Probably somebody can give me some pointers, though? I am doing this: gsap.utils.toArray(".book").forEach((book) => { var bookImageSRC = book.querySelector("img").src; var bookImageNaturalHeight = book.querySelector("img").naturalHeight; var bookImageNaturalWidth = book.querySelector("img").naturalWidth; var bookImageProportion = bookImageNaturalWidth / bookImageNaturalHeight; var bookImageTargetWidth = 200; var bookImageTargetHeight = bookImageTargetWidth / bookImageProportion; function bookHover(e) { if (e.type === "mouseenter") { var tl_bookIn = gsap.timeline(); tl_bookIn.set(bookImageWrapper, {backgroundImage: "url('" + bookImageSRC + "'", backgroundSize: bookImageTargetWidth + "px " + bookImageTargetHeight + "px", width: bookImageTargetWidth*0.9, height: bookImageTargetHeight*0.9}); tl_bookIn.set(book, {backgroundColor: "#FF89E4"}); tl_bookIn.to(bookImageWrapper, {autoAlpha: 1, rotate: 10, backgroundSize: bookImageTargetWidth + "px " + bookImageTargetHeight + "px", width: bookImageTargetWidth, height: bookImageTargetHeight, duration: 1.6}); } else if (e.type === "mouseleave") { var tl_bookOut = gsap.timeline(); tl_bookOut.set(book, {backgroundColor: "#F2FF74"}); tl_bookOut.to(bookImageWrapper, {autoAlpha: 0, rotate: 0, backgroundSize: bookImageTargetWidth * 1.2 + "px " + bookImageTargetHeight * 1.2 + "px", width: bookImageTargetWidth*0.6, height: bookImageTargetHeight*0.6, duration: 1}); } } book.addEventListener("mouseenter", bookHover); book.addEventListener("mouseleave", bookHover); book.addEventListener("mousemove", moveBookImage); }); Then I try to kill the timeline like this: return function() { // other cleanup code can go here. tl_bookIn.kill(); tl_bookOut.kill(); }; But it says 'Can't find variable: tl_bookIn'. This probably has to do with scope? Codepen example here: See the Pen rNwogyM?editors=1010 by wildeweg (@wildeweg) on CodePen Link to comment Share on other sites More sharing options...
GreenSock Posted September 28, 2021 Share Posted September 28, 2021 Yep, that's just a JavaScript scope thing. Whenever you create a variable with "const" or "let" or "var", that's called a LOCAL variable, meaning it is only accessible from INSIDE that function. So if you need to reference it OUTSIDE that function, you've got a few options: // declare the variable OUTSIDE the function let tl_bookIn; function whatever() { tl_bookIn = gsap.timeline(); // assign it inside the function ... } -OR- let tl_bookIn = makeBookIn(); // return the timeline from the function and assign it to your variable here. function makeBookIn() { let tl = gsap.timeline(); ... return tl; // <-- IMPORTANT! Return the timeline } Does that help? 1 Link to comment Share on other sites More sharing options...
OSUblake Posted September 28, 2021 Share Posted September 28, 2021 Juts to show what Jack was talking about. See the Pen QWgzebm by GreenSock (@GreenSock) on CodePen 2 Link to comment Share on other sites More sharing options...
pixelpillow Posted September 28, 2021 Share Posted September 28, 2021 Thanks a lot! I actually tried to declare the variable outside the function, but than the animation started behaving strange, so apparently I did something wrong. This helps a lot! I'll take a deep dive! Link to comment Share on other sites More sharing options...
pixelpillow Posted September 28, 2021 Share Posted September 28, 2021 Hmm. I don't get the 'can't find variable' error anymore, but it also doesn't seem to kill anything... Link to comment Share on other sites More sharing options...
OSUblake Posted September 28, 2021 Share Posted September 28, 2021 You still have event listeners attached. You would need to remove those as well. See the Pen LYLqPrd by GreenSock (@GreenSock) on CodePen 1 Link to comment Share on other sites More sharing options...
pixelpillow Posted September 28, 2021 Share Posted September 28, 2021 Ah, I see. Get the idea. Will try to comprehend your solution. Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now