clieee Posted October 7, 2020 Share Posted October 7, 2020 Hi, I have a page where I have x number of containers/divs. Some of these have defined background colors, and should thereby change body background color once they getting visible as you scroll down. But also change back to their color if user scrolls back up. I'm using React and my thought was to create a custom hook that I connect to the node/container/div that should be used as trigger. That is all working fine, if that seems to be a good approach, I basically create a new ScrollTrigger every time that hook is being used. However, some questions: - I guess I have to use the callbacks for onEnter and onEnterBack in order to add/remove the body background color class? - What should my start values be? "top top" (=if top of element hits top of viewport) if a "colored" section is a top of page? And for other sections "top bottom" (=if top of element reaches bottom of viewport)? - If the first section on the page should set a specific background color, and then the user scrolls down a bit, the next section becomes visible = trigger color change, but then the user scrolls back up again, how can I tell if it should transition back to it's color again then? onEnterBack wont get triggered in this case..? Link to comment Share on other sites More sharing options...
ZachSaucier Posted October 7, 2020 Share Posted October 7, 2020 1 hour ago, clieee said: I guess I have to use the callbacks for onEnter and onEnterBack in order to add/remove the body background color class? Sure, that works. Or you could animate the backgroundColor directly (not use classes). 1 hour ago, clieee said: What should my start values be? "top top" (=if top of element hits top of viewport) if a "colored" section is a top of page? And for other sections "top bottom" (=if top of element reaches bottom of viewport)? That makes sense. It depends on when you want it to happen 1 hour ago, clieee said: If the first section on the page should set a specific background color, and then the user scrolls down a bit, the next section becomes visible = trigger color change, but then the user scrolls back up again, how can I tell if it should transition back to it's color again then? onEnterBack wont get triggered in this case..? It'd probably make more sense to use the onEnter and onLeaveBack for this sort of thing. You can save the colors to a list and use that. I did this same sort of thing in this thread (without React): This thread is very similar as well: 3 Link to comment Share on other sites More sharing options...
clieee Posted October 7, 2020 Author Share Posted October 7, 2020 Thanks! Link to comment Share on other sites More sharing options...
Mlbb lan Posted January 15, 2022 Share Posted January 15, 2022 guys, can you help me? I want to change the background color when I click I use the code: gsap.utils.toArray(".section").forEach(function (elem) { var color = elem.getAttribute('data-color'); ScrollTrigger.create({ trigger: elem, start: 'top 30%', end: 'bottom 30%', markers: false, onEnter: () => gsap.to('main', { backgroundColor: color, duration: 1.4 }), onLeave: () => gsap.to('main', { backgroundColor: '#fef9ef', duration: 1.4 }), onLeaveBack: () => gsap.to('main', { backgroundColor: '#fef9ef', duration: 1.4 }), onEnterBack: () => gsap.to('main', { backgroundColor: color, duration: 1.4 }), }); }); this is to change the background color when switching to another section Now I want to use simple code: const elem = document.querySelector(".section.hero"); const switcher = document.querySelector(".switch-theme"); switcher.addEventListener('click', function() { if (elem.hasAttribute == ('data-color', "#FEF9EF") { this.setAttribute = ('data-color', "#000000"); } }); To click on the element to change the color of my section, but I get an error instead Is it possible to change the data-color dynamically somehow? Link to comment Share on other sites More sharing options...
OSUblake Posted January 15, 2022 Share Posted January 15, 2022 Hi @GeorgeErshov Can you create a new topic with your question and include a minimal demo? Thanks! Link to comment Share on other sites More sharing options...
GreenSock Posted January 16, 2022 Share Posted January 16, 2022 This is definitely wrong: // BAD if (elem.hasAttribute == ('data-color', "#FEF9EF") { this.setAttribute = ('data-color', "#000000"); } // GOOD (maybe? I'm not sure what your intent is) if (elem.getAttribute('data-color') === "#FEF9EF") { elem.setAttribute('data-color', "#000000"); } You could also simplify your ScrollTrigger: // OLD ScrollTrigger.create({ trigger: elem, start: 'top 30%', end: 'bottom 30%', markers: false, onEnter: () => gsap.to('main', { backgroundColor: color, duration: 1.4 }), onLeave: () => gsap.to('main', { backgroundColor: '#fef9ef', duration: 1.4 }), onLeaveBack: () => gsap.to('main', { backgroundColor: '#fef9ef', duration: 1.4 }), onEnterBack: () => gsap.to('main', { backgroundColor: color, duration: 1.4 }), }); // NEW ScrollTrigger.create({ trigger: elem, start: 'top 30%', end: 'bottom 30%', onToggle: (self) => gsap.to('main', { backgroundColor: self.isActive ? color : '#fef9ef', duration: 1.4 }) }); If you need more help, please provide a minimal demo in CodePen or something like that. Happy tweening! Link to comment Share on other sites More sharing options...
Mlbb lan Posted January 23, 2022 Share Posted January 23, 2022 On 1/16/2022 at 1:07 AM, OSUblake said: Hi @GeorgeErshov Can you create a new topic with your question and include a minimal demo? Thanks! Hi, sorry it took so long Here's a simple demonstration. I want to click-me button (class='change-color') to change the color of all sections that have data-color, to a different color (the designer came up with a dark theme) See the Pen RwLXmwB by GeorgeDesign2020 (@GeorgeDesign2020) on CodePen Link to comment Share on other sites More sharing options...
OSUblake Posted January 24, 2022 Share Posted January 24, 2022 Hi George, I'm still not sure what you are trying to do. You have ScrollTrigger code that is changing the background, but now you you are saying you want a button to change to background, so which is it? Link to comment Share on other sites More sharing options...
Mlbb lan Posted January 25, 2022 Share Posted January 25, 2022 14 hours ago, OSUblake said: Привет Джордж, Я все еще не уверен, что вы пытаетесь сделать. У вас есть код ScrollTrigger, который меняет фон, но теперь вы говорите, что хотите, чтобы кнопка менялась на фон, так что же это? I want to change the attributes of the sections by clicking on this button, I want the data-color to change For example: class='section s-1' has data-color='#838C8B'. By clicking on the button, I want to change the data-color='#000000' make the background black, and in the section class='section s-2' make the data-color='#ffffffff' Here's the site I'm working on, here the designer wants me to change the colors to contrasting (black and white) for the visually impaired when I click on the eye https://function-x-siberia-site.webflow.io/ Link to comment Share on other sites More sharing options...
Cassie Posted January 25, 2022 Share Posted January 25, 2022 Hi George! You haven't got any logic in place for the button at all. What have you tried so far? You'll likely need to toggle a boolean like so. let contrastMode button.addEventListener(click, (e) => { contrastMode = !contrastMode; if(contrastMode) { // make sections black and white } else { // make sections original colors } }) If you give it a go we can help to nudge you in the right direction, but unfortunately we don't offer free custom solutions in these forums. The GSAP part would be similar to what you have here already - just a tween that changes color. The tricky bit will be the logic of what happens with the scrollTrigger when the state changes - if you need scrollTriggered sections that change color too you'll need to use variables for the colors, update them in your logic loop and call scrollTrigger.refresh() to update the values 2 Link to comment Share on other sites More sharing options...
Mlbb lan Posted January 25, 2022 Share Posted January 25, 2022 7 hours ago, Cassie said: Hi George! You haven't got any logic in place for the button at all. What have you tried so far? You'll likely need to toggle a boolean like so. let contrastMode button.addEventListener(click, (e) => { contrastMode = !contrastMode; if(contrastMode) { // make sections black and white } else { // make sections original colors } }) If you give it a go we can help to nudge you in the right direction, but unfortunately we don't offer free custom solutions in these forums. The GSAP part would be similar to what you have here already - just a tween that changes color. The tricky bit will be the logic of what happens with the scrollTrigger when the state changes - if you need scrollTriggered sections that change color too you'll need to use variables for the colors, update them in your logic loop and call scrollTrigger.refresh() to update the values Hi, yes i already tried to do different things with both jquery and javascript Please look now, I added some very simple code $('.change-color').click(function() { $("#id").attr("data-color","#000000"); console.log('change dark-mode'); scrollTrigger.refresh() }) See the Pen RwLXmwB by GeorgeDesign2020 (@GeorgeDesign2020) on CodePen But nothing happens, I seem to be calling the scrolltrigger.refresh() method incorrectly Link to comment Share on other sites More sharing options...
OSUblake Posted January 25, 2022 Share Posted January 25, 2022 Hi George, This is will be only read 1 time. That's just how JavaScript works. var color = elem.getAttribute('data-color'); If you need it to update, you're going to have to provide a way to update the value inside of the forEach. I just used map to create an array of functions that will update the color value and set the background if the trigger is active. See the Pen mdqdqNV by GreenSock (@GreenSock) on CodePen 1 1 Link to comment Share on other sites More sharing options...
Mlbb lan Posted January 26, 2022 Share Posted January 26, 2022 11 hours ago, OSUblake said: Thank you so much! It works great! 1 Link to comment Share on other sites More sharing options...
fernandocomet Posted April 1 Share Posted April 1 What if I have: - Many sections - Only some of them change background color - I just want to target each sections If you see this demo See the Pen PogOQQr by fernandocomet (@fernandocomet) on CodePen First two are ok, but I am changing the color to all classes with naming "sectiontrigger". What if I just want to target the current section on the viewport? What is the best approach? Link to comment Share on other sites More sharing options...
Rodrigo Posted April 1 Share Posted April 1 Hi @fernandocomet, I'm not 100% sure of what you're trying to achieve here so I took my best guess in this demo: See the Pen XWQzYaR by GreenSock (@GreenSock) on CodePen Hopefully this helps, if not please be more especfic about what you're trying to achieve. Happy Tweening! Link to comment Share on other sites More sharing options...
fernandocomet Posted April 1 Share Posted April 1 Oh sorry and thanks Rodrigo. The issue I have is that if I apply the transformation to class "sectiontrigger", all sections with that class change their color. So I just want to change the color of each one when the user reachs them, but keeping their color when not. So I have these sections, defining background Color initially: .hero{ background-color: MediumSeaGreen; } .s1{ background-color: SlateBlue; } .s3{ background-color: DodgerBlue; } .s5{ background-color: tomato; } .s7{ background-color: gold; } I just want to change the color of these sections to their "data-color" attribute <section data-color='#FF6347' class='section sectiontrigger'>Section 1</section> <section class='section'>Section 2</section> <section data-color='#7FFF00' class='section sectiontrigger'>Section 3</section> <section class='section'>Section 4</section> <section data-color='#00FFFF' class='section sectiontrigger'>Section 5</section> <section class='section'>Section 6</section> <section data-color='#FF7F50' class='section sectiontrigger'>Section 7</section> <section class='section'>Section 8</section> But I want to keep the initial color (when the ScrollTrigger is not active), so the change should not affect all sections Doing as many scrollTriggers as sections I want to change is not a good approach. Link to comment Share on other sites More sharing options...
Rodrigo Posted April 1 Share Posted April 1 No problemo, Mondays are always tough: Actually creating a ScrollTrigger instance for each section is a good approach actually, I think you're just overcomplicating this a bit. Just use a single GSAP Tween controlled with ScrollTrigger toggle actions: const sections = gsap.utils.toArray(".sectiontrigger"); sections.forEach(function (section, i) { var color = section.getAttribute("data-color"); gsap.to(section, { backgroundColor: color, ease: "power1.inOut", scrollTrigger: { trigger: section, start: "top 50%", end: "bottom 95%", markers: true, toggleActions: "play none none reverse", }, }); }); Here is the updated demo: See the Pen XWQzYaR by GreenSock (@GreenSock) on CodePen Hopefully this helps. Happy Tweening! Link to comment Share on other sites More sharing options...
fernandocomet Posted April 3 Share Posted April 3 That looks good Rodrigo Thanks a lot I am experimenting right now with Glaze, so it is GSAP + Data Attributes. Some NoCode tools use this approach See here See the Pen bGJYXJO by fernandocomet (@fernandocomet) on CodePen What is the correct approach if I want Section 1 to disappear when it is out of the viewport, and if the User comes again repeat the animation? Not sure if I should touch something on ToggleActions or better in the ScrollTrigger Start/Stop settings. For ToggleActions (onEnter, onLeave, onEnterBack, onLeaveBack) I have: [play_reverse_play_reverse] For ScrollTrigger settings I have: start-[top_50%] end-[bottom_95%] Link to comment Share on other sites More sharing options...
Rodrigo Posted April 3 Share Posted April 3 Hi, I'm not sure I follow 100% what you're trying to do but maybe something like this: See the Pen YzMYJMJ by GreenSock (@GreenSock) on CodePen That's the approach I would follow in order to show/hide an element that has the height of the viewport, based on it's position in the viewport. Keep in mind that end: "bottom 95%" means that the ScrollTrigger end point will be at almost the bottom of the viewport (95%, with the top being 0%) and the bottom of the element will hit that almost immediately after the top passes the top of the viewport. Here is what the ScrollTrigger docs have about start, end and toggleActions: start String - Describes a place on the trigger and a place on the scroller that must meet in order to start the ScrollTrigger. So, for example, "top center" means "when the top of the trigger hits the center of the scroller" (and the scroller is the viewport by default). "bottom 80%" means "when the bottom of the trigger hits 80% down from the top of the viewport" (assuming vertical scroll). You can use keywords like "top", "bottom", "center" (or "left" and "right" if horizontal: true) or percentages like "80%" or pixel values like "100px". Percentages and pixels are always relative to the top/left of the element/scroller. You can even use a complex relative value like "top bottom-=100px" which means "when the top of the trigger hits 100px above the bottom of the viewport/scroller" end String - Describes a place on the endTrigger (or trigger if one isn't defined) and a place on the scroller that must meet in order to end the ScrollTrigger. So, for example, "bottom center" means "when the bottom of the endTrigger hits the center of the scroller". "center 100px" means "when the center of the endTrigger hits 100px down from the top of the scroller" (assuming vertical scroll). You can use keywords like "top", "bottom", "center" (or "left" and "right" if horizontal: true) or percentages like "80%" or pixel values like "100px". Percentages and pixels are always relative to the top/left of the element/viewport. You can also define a single relative value like "+=300" which means "300px beyond where the start is", or "+=100%" means "the height of the scroller beyond where the start is". "max" is a special keyword indicating the maximum scroll position. toggleActions String - Determines how the linked animation is controlled at the 4 distinct toggle places - onEnter, onLeave, onEnterBack, and onLeaveBack, in that order. The default is play none none none. So toggleActions: "play pause resume reset" will play the animation when entering, pause it when leaving, resume it when entering again backwards, and reset (rewind back to the beginning) when scrolling all the way back past the beginning. You can use any of the following keywords for each action: "play", "pause", "resume", "reset", "restart", "complete", "reverse", and "none". Hopefully this helps. Happy Tweening! 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