una Posted February 13 Share Posted February 13 Hi, I am trying to change each nav item color from white to black or back depending on the section class (i.e background color) behind it. The navigation is fixed as the content comprised of sections with class="section-white" or class= "section-dark" scrolls beneath it. The script below changes all links simultaenously. Has anyone any suggestion as to what I am doing wrong? Thanks! const sections = gsap.utils.toArray('.section-white'); sections.forEach(section => { ScrollTrigger.create({ trigger: section, duration:3, start: 'top 300px', end: 'bottom 80px', scrub: 1, toggleClass: { targets: '.nav-link', className: 'text-black' }, markers: true, }) }); See the Pen rNRQrvm by fatcatsanonymous (@fatcatsanonymous) on CodePen Link to comment Share on other sites More sharing options...
GSAP Helper Posted February 13 Share Posted February 13 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? 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 dependancies 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: React (please read this article!) Next Svelte Sveltekit Vue Nuxt 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. ✅ Link to comment Share on other sites More sharing options...
Rodrigo Posted February 13 Share Posted February 13 Hi, @Carl made a great video explaining how to do this, be sure to check the codepen link in the video description as well: Hopefully this helps. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
una Posted February 14 Author Share Posted February 14 Hi, Thanks for this tip. I did watch this tutorial already actually, but it doesn't solve my issue unfortunately. I added a codepen above to show where I'm at. The nav item color is changing but I would like each instance to change as it enters the section. Otherwise, as the user scrolls and is halfway through the navigation you have white links on white background. Link to comment Share on other sites More sharing options...
mvaneijgen Posted February 14 Share Posted February 14 22 hours ago, una said: The script below changes all links simultaenously. Has anyone any suggestion as to what I am doing wrong? Right now you only loop through the sections, but you want to change the .nav-link one by one, so you need another loop that does this but then for each .nav-link, this does mean that we're creating as many ScrollTriggers as there are sections * .nav-link items, which means there are a lot! You do have to calculate the offset of each .nav-link I now used some random fixed values which are good enough to show in the demo and explain the concept, but you probably want to get that dynamically so that it is more robust on different screen sizes. There is probably a better way of doing this. A timeline animation with a stagger what just changes each .nav-link color one by one instead of a class and than setting the ScrollTrigger to scrub: true, so that it plays the animation on scroll, but that is why Codepen is great. Personally I use codepen to try out new ideas, I usually then just keep forking my pen to try out different ideas, either because I think it could be better or my original idea was not working. Usually at version 10 I got something I'm happy with. Creating forks of your pen will allow you to fall back at earlier ideas if something new is not working. See the Pen poYqNPx?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen In this case if you're not going to animate things why not just set mix-blend-mode: difference; in CSS I'm not sure if there is a better blend more for the colors you use, but this gets you 90% there for free. See the Pen zYbyopO?editors=0100 by mvaneijgen (@mvaneijgen) on CodePen 3 Link to comment Share on other sites More sharing options...
una Posted February 18 Author Share Posted February 18 Hi mvaneijgen, Thanks so much for this. I don't quite understand the offset though. Regardless how I set these values, The markers are not in line with the nav items... Regarding mix-blend-mode, I had thought of using this as a simple solution too, however as it is a fixed navigation above not within the background sections, the background-colors of the sections have no relation to it so this won't work. As I have GSAP incorporated anyway for other animations it seemed the best solution to use it for the nav also. I'll post the results. 1 Link to comment Share on other sites More sharing options...
una Posted February 22 Author Share Posted February 22 Hi, I'm still not getting anywhere with the offset. Even playing around with the fixed values isn't positioning the markers correctly. Link to comment Share on other sites More sharing options...
mvaneijgen Posted February 22 Share Posted February 22 Hi @una we can't really help without a minimal demo. Link to comment Share on other sites More sharing options...
una Posted February 26 Author Share Posted February 26 Hi, Sorry should have shared my last results, but I haven't really gotten anywhere aside from adding/changing some fixed values to your solution . I don't really know how to generate these... See the Pen JjzgpJJ by fatcatsanonymous (@fatcatsanonymous) on CodePen Link to comment Share on other sites More sharing options...
Solution Rodrigo Posted February 26 Solution Share Posted February 26 Hi, I checked your last demo and it seems to be working as expected. What exactly is the issue you're having? I forked your demo and instead of using hardcoded values for each element's offset I used the getBoundingClientRect method: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect This is a fork of your latest demo: See the Pen mdoNxoe by GreenSock (@GreenSock) on CodePen Hopefully this helps. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
una Posted February 27 Author Share Posted February 27 Hi Thanks so much for this. The fixed values were exactly my issue. @mvaneijgen kindly helped me out with the second loop which was my initial problem. So many thanks to both of you for your expertise and help! 2 Link to comment Share on other sites More sharing options...
una Posted March 11 Author Share Posted March 11 I'm back on this issue again. I'm trying to refresh the marker positions when a submenu is opened. I've added a submenu dropdown script with a ScrollTrigger.refresh() but this is not working for me. See the Pen gOyaVOj by fatcatsanonymous (@fatcatsanonymous) on CodePen Link to comment Share on other sites More sharing options...
mvaneijgen Posted March 11 Share Posted March 11 You need to wait until it has fully opened and then call ScrollTrigger.refresh(); If you build the toggle with GSAP you can hook it in the onComplete callback of the tween. How you've set it up now I don't know how you would do that, maybe there are jQuery hooks you can use, but I can't advise you on that. But that said you've GSAP super powers now, so simply changing a class is a bit simple, right? You've of course want to build an animating with each item staggering in one by one anyway! Link to comment Share on other sites More sharing options...
Rodrigo Posted March 11 Share Posted March 11 Yeah, you should do that here after toggling the class: $("ul li.dropdown").on("click", function () { $(this).toggleClass("show-dropdown-menu"); ScrollTrigger.refresh(); }); Finally is worth noticing that this is not going to work: const navLinks = gsap.utils.toArray(".nav-link"); navLinks.addEventListener("click", (event) => { }); The navLinks constant is an array and you can't attach an event listener on an array: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array Happy Tweening! Link to comment Share on other sites More sharing options...
una Posted March 11 Author Share Posted March 11 Thanks to you both - you're so fast! I had tried adding the Scrolltrigger.refresh to the toggle function but this doesn't work somehow. I assume also it will refresh all scrolltrigger markers from other animations on the page in question, which is not great either. I guess I'll look into using GSAP to rebuild the menu dropdown and go from there. ... haven't really figured outhow to tap into those superpowers that I now have, though! Link to comment Share on other sites More sharing options...
Rodrigo Posted March 11 Share Posted March 11 Hi, Since you have an array with all the sections that you loop trough to create the ScrollTrigger instances, you can store those ScrollTrigger instances in another array, in order to loop through and refresh just those: const stArray = []; sections.forEach(() => { navLinks.forEach((item, index) => { const rect = item.getBoundingClientRect(); stArray.push(ScrollTrigger.create({ trigger: section, start: `top ${rect.y}`, end: `bottom ${rect.y + rect.height}`, scrub: 1, toggleClass: { targets: item, className: "text-black" }, markers: true })); }); }); Then in your code: $("ul li.dropdown").on("click", function () { $(this).toggleClass("show-dropdown-menu"); stArray.forEach((st) => st.refresh()); }); Happy Tweening! 2 Link to comment Share on other sites More sharing options...
una Posted March 12 Author Share Posted March 12 Sorry, I can't seem to get this working ... See the Pen gOyaVOj by fatcatsanonymous (@fatcatsanonymous) on CodePen Link to comment Share on other sites More sharing options...
mvaneijgen Posted March 12 Share Posted March 12 When you use function based values and call ScrollTrigger.refresh() these values get recalculated. If you don't use function based values, but use functions in your values, ScrollTrigger will think they do not update and keeps the values it has calculated on initial load. I've also moved the item.getBoundingClientRect() in to the value, to be sure it recalculates the values. Hope it helps and happy tweening! See the Pen ZEZOOEv?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen 2 Link to comment Share on other sites More sharing options...
una Posted March 12 Author Share Posted March 12 ... works a dream! Thanks again to you both, not only for your generous work on solutions, but also for the informative insights on working with GSAP! 1 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