Jump to content
Search Community

All Activity

This stream auto-updates

  1. Past hour
  2. Hey @Rodrigo, This approach is not working for me, is there any other way to stop touchpad too many scroll events? Or is there something wrong with my code. const gsapInitialization = () => { console.log("gsapInitialization is done...") gsap.registerPlugin(ScrollTrigger); gsap.config({ easeInOutCubic: function (progress) { return progress < 0.5 ? 4 * progress ** 3 : 1 - Math.pow(-2 * progress + 2, 3) / 2; } }); // let sectionEase = "Power1.easeInOut"; let sectionEase = "easeInOutCubic"; // let slideEase = "Power1.easeInOut"; let slideEase = "power3.easeinOut"; let otherAnimationEase = "easeInOutCubic"; let sectionDuration = 0.7; let slideDuration = 0.6; // VodaMedia Development Page Specific GSAP Animation gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); gsap.registerPlugin(Observer); let mastertl = gsap.timeline({ paused: true, defaults: { // ease: "power3.inOut", // ease: "Power1.easeInOut", ease: otherAnimationEase, duration: 0.3, autoAlpha: 0, }, }); gsap.set('.graph_slide_heading', { width: window.innerWidth >= 767 ? 550 : 240, y: 100, autoAlpha: 0, }) mastertl .from('.banner_description', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.horizontal_scroller_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.hs_container_1_text', { xPercent: -100, // onComplete: () => (isTweening = false), }) .addPause() .to('.hs_inner', { xPercent: -50, autoAlpha: 1, ease: slideEase, delay:0.5, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.one_col_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.one_col_text', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.two_col_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.tc_telco_content', { y: 200, autoAlpha: 0, // onComplete: () => (isTweening = false), }) .from('.tc_telco_image', { y: 100, autoAlpha: 0, // onComplete: () => (isTweening = false), }, "<") .addPause() .to('.tc_telco_content', { y: -100, height: 0, autoAlpha: 0, // onComplete: () => (isTweening = false), }) .from('.tc_digital_content', { y: 100, height: 0, autoAlpha: 0, // onComplete: () => (isTweening = false), }, "<") .to('.tc_telco_image_container', { autoAlpha: 1, scrollTo: { y: '.tc_telco_image_in_2', autoKill: false, ease: sectionEase, } }, "<") .addPause() .to(window, { scrollTo: { y: '.two_col_module_V2', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.tcV2_main_slide_heading ', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to('.two_col_module_V2_inner', { xPercent: window.innerWidth >= 767 ? -60 : -100, autoAlpha: 1, ease: slideEase, duration: slideDuration, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.two_col_logo_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.two_col_logo_heading, .two_col_logo_description', { y: 100, // onComplete: () => (isTweening = false), }) .from('.two_col_logo_module .two_col_logo_image', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.graph_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) // .from('.graph_module_heading', { // y: 100, // }).addPause() // .to('.graph_module_inner', { // xPercent: -100, // autoAlpha: 1, // ease:slideEase, // duration:slideDuration, // }) // .from('.graph_slide_heading, .graph_module_image', { // y: 100, // stagger: 0.8, // }) .to('.graph_slide_heading', { y: 0, autoAlpha: 1, // onComplete: () => (isTweening = false), }) .addPause() .to('.graph_slide_heading', { width: window.innerWidth >= 1024 ? 350 : (window.innerWidth >= 767 ? 240 : "100%"), autoAlpha: 1, ease: sectionEase, // onComplete: () => (isTweening = false), }) .from(' .graph_module_image', { x: 100, // onComplete: () => (isTweening = false), }, "<") .addPause() .to(window, { scrollTo: { y: '.logo_slider_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.logo_slider_heading , .logo_slider_description', { y: 100, // onComplete: () => (isTweening = false), }) .from(' .logo_slider_module .two_col_logo_container', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.one_col_module_V2_r', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.one_col_module_V2_r .one_col_V2_heading', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() .to(window, { scrollTo: { y: '.contact_us_module', autoKill: false }, duration: sectionDuration, ease: sectionEase, }) .from('.contact_us_heading, .contact_us_description, .contact_us_form_container', { y: 100, // onComplete: () => (isTweening = false), }) .addPause() // let isTweening = false; // console.log(isTweening); // Observer For Timeline Observer.create({ type: "wheel, touch, pointer, touchmove", target: window, preventDefault: true, wheelSpeed: -1, tolerance: 100, dragMinimum: window.innerWidth >= 480 ? 100 : 20, onUp: () => { // if (isTweening) return; // isTweening = true; // console.log(isTweening); if (mastertl.totalProgress() < 1) { mastertl.play(); } }, onDown: () => { // if (isTweening) return; // isTweening = true; // console.log(isTweening); if (mastertl.totalProgress() <= 1) { mastertl.reverse(); } }, }); // Animation on Arrow Key document.onkeydown = CheckKeyFun; function CheckKeyFun(key) { key.preventDefault(); if (key.keyCode == '38') { // console.log("Up arrow"); if (mastertl.totalProgress() <= 1) { mastertl.reverse(); } } else if (key.keyCode == '40') { // console.log("Down arrow"); if (mastertl.totalProgress() < 1) { mastertl.play(); } } } // Nav Menu Link To Sections let hamIcon = document.querySelector('#headerModule .hamIcon'); hamIcon.onclick = linkListenerToNav; function linkListenerToNav() { let navTimeout = setTimeout(function () { // Menu Navbar let whatSetUsApartNav = document.querySelector('#menu-1-749d960 .whatSetUsApartMenu .elementor-item-anchor'); let whatDoWeDoNav = document.querySelector('#menu-1-749d960 .whatDoWeDoMenu .elementor-item-anchor '); let whatDoWeOfferNav = document.querySelector('#menu-1-749d960 .whatDoWeOfferMenu .elementor-item-anchor'); let ourClientsNav = document.querySelector('#menu-1-749d960 .ourClientsMenu .elementor-item-anchor'); let socialImpactNav = document.querySelector('#menu-1-749d960 .socialImpactMenu .elementor-item-anchor'); let contactUsNav = document.querySelector('#menu-1-749d960 .contactUsMenu .elementor-item-anchor'); const navMenu = [whatSetUsApartNav, whatDoWeDoNav, whatDoWeOfferNav, ourClientsNav, socialImpactNav, contactUsNav]; navMenu.forEach((menuItem) => { menuItem.addEventListener('click', function (e) { e.preventDefault(); if (menuItem.parentElement.classList.contains("whatSetUsApartMenu")) { // console.log("whatSetUsApart"); mastertl.progress(0.038).play(); } else if (menuItem.parentElement.classList.contains("whatDoWeDoMenu")) { // console.log("whatDoWeDoMenu"); mastertl.progress(0.19).play(); } else if (menuItem.parentElement.classList.contains("whatDoWeOfferMenu")) { // console.log("whatDoWeOfferMenu"); mastertl.progress(0.39).play(); } else if (menuItem.parentElement.classList.contains("ourClientsMenu")) { // console.log("ourClientsMenu"); mastertl.progress(0.752).play(); } else if (menuItem.parentElement.classList.contains("socialImpactMenu")) { // console.log("socialImpactMenu"); mastertl.progress(0.856).play(); } else if (menuItem.parentElement.classList.contains("contactUsMenu")) { // console.log("contactUsMenu"); mastertl.progress(0.93196).play(); } }) }) }, 100) } } window.addEventListener('load', gsapInitialization) // Scroll To Top Function function smoothScrollToTop() { // console.log('smoothscroll'); const rootElement = document.documentElement; rootElement.scrollTo({ top: 0, behavior: "smooth" }); } smoothScrollToTop(); window.addEventListener("load", smoothScrollToTop); window.addEventListener("beforeunload", smoothScrollToTop); document.addEventListener("load", smoothScrollToTop);
  3. @Rodrigo first of all thanks for acknowledge my reply and the solution did not work by the way my problem in same and when i run my build folder the scroll automatically to the end without my scroll i use pin the image scroll system in which it scroll horizontall to the end at the start point not with the scroll bar see if you have any solution Happy tweening
  4. Today
  5. Also any suggest for a better way to make content scroll to center without hard code to add blank items before and after?
  6. Hello GSAP Community, I am working on a Vue 3 project and facing an issue with implementing RTL support for a tab navigation system where the active tab should center on click. My current implementation with GSAP's ScrollToPlugin works fine for LTR, but fails in RTL mode. Tabs are dynamically generated and centered using scrollTo from GSAP when clicked. Current Issue: Adding dir="rtl" to my scroll container breaks the centered alignment of the tabs. The function calculating the scroll position seems to not accommodate RTL. I tried to not use RTL direction and reverse sort the data + unshift when add new items but its a lot of works and introduce more bugs so if i can get help to fix RTL instead it will be the best choice. Thanks for your help
  7. Thanks, Rodrigo! And oof, that AI landing page is actually fairly heavy on the machine I use for perf testing, tho I feel it's likelier due to the assets than the scrolltriggers. (Run down late 2010s macbook pro with lots of browser tabs/windows open.) Anyway, I massively fixed my own perf since posting here, tho the solution is unrelated to GSAP. I have 14 SVGs with identical paths but differing in fill and stroke, and using GSAP to stagger them. Perf was not acceptable before — when I was inlining the SVGs (also tried importing them as component but no change - background-image is a no-go because I need dynamic styling from CSS variables). But! I finally tried out sprites in React/Next - was a little finnicky getting the styles to apply correctly, but wow, buttery smooth scrolling now. I probably no longer need to worry about multiple or single scrolltriggers now. Like you say, it's far better to maintain components with scoped functionality, with the exception of state or ref props or whatever. Good to know that multiple scrolltriggers are not really an issue tho.
  8. Yesterday
  9. Hi, I would always try to keep the animations for each component inside the component. Often is said as a best practice in React that a component should do just one thing, so I'm not really into the approach of having a component handling animations of elements that are not rendered by that component. I have a couple of code bases but those are protected by NDAs so I can't share them. One is this: https://wiredave.com/artificial-intelligence That's GSAP & Next(12), the project manager always talked about moving away to Nuxt for several reasons I won't share here but it seems they're still using Next. Every section in that site, regardless how small and simple it is, is a component and the animation resides inside the component and you can see that there is no lag, FOUC or any other issue with the initial load. There is no real gain in terms of creating a number of GSAP instances rather than just one, unless you create thousands of them at the same time, which rarely is the case. Also is always better to make your files more concise and smaller in order to make maintenance easier down the road. In 3 to 6 months or perhaps a few years down the road, it'll be far easier to decipher what you're doing in a smaller file rather than a large one. Those are my two cents on the subject. Hopefully this helps. Happy Tweening!
  10. Hi, Sorry to hear about the issues, but the demo is working as expected, so definitely is not a GSAP related issue. Most likely something else in your setup (CSS most likely) is interfering with this, so you'll have to look for that. Also keep in mind that the particular demo that was linked is using this stylesheet as well: https://codepen.io/GreenSock/pen/xxmzBrw.css Maybe the styles you're missing are there. Hopefully this helps. Happy Tweening!
  11. Hi, Two things. First, proper cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE. Since GSAP 3.12, we have the useGSAP() hook (the NPM package is here) that simplifies creating and cleaning up animations in React (including Next, Remix, etc). It's a drop-in replacement for useEffect()/useLayoutEffect(). All the GSAP-related objects (animations, ScrollTriggers, etc.) created while the function executes get collected and then reverted when the hook gets torn down. Here is how it works: const container = useRef(); // the root level element of your component (for scoping selector text which is optional) useGSAP(() => { // gsap code here... }, { dependencies: [endX], scope: container }); // config object offers maximum flexibility Or if you prefer, you can use the same method signature as useEffect(): useGSAP(() => { // gsap code here... }, [endX]); // simple dependency Array setup like useEffect() This pattern follows React's best practices. We strongly recommend reading the React guide we've put together at https://gsap.com/resources/React/ Two, you have this on your setup: onUpdate: (self) => { const progress = self.progress; const index = Math.floor(progress * images.length); // HERE setCurrentPrayerIndex(index); gsap.set(`#image-${currentPrayerIndex}`, { rotation: 0, scale: 1, zIndex: prayers.length, }); // Reset rotation, scale, and z-index }, The onUpdate callback of a ScrollTrigger instance is going to fire everytime the scroll position is updated. Do you really want to update the state of your component everytime the user scrolls? On top of that since that state property you're updating is on the useEffect hook and you're not doing proper cleanup, the GSAP Timeline is being created again and again and again, so everytime the user scrolls you have more and more GSAP Timelines and ScrollTrigger instances, which is a memory leak. I would strongly recommend you to not use ScrollTrigger for now, just focus on creating the animation. Once the animation is working the way you intend, then you can add ScrollTrigger back into the mix. Also take a look at the useGSAP hook and the article link I shared in order to bbetter understand how things are wired up when using GSAP in a react app. Happy Tweening!
  12. Hi, This is not actually related to GSAP but just the way browsers work and the inner works ScrollTrigger has to do in order to do it's calculations. ScrollTrigger takes the page back to the top in order to make the calculations and make sure everything is rendered and positioned the way it should, something that is more difficult if the scroll position is not at the top. In your particular case, since you have toggleActions in your setup, that tells ScrollTrigger to play the timeline which hides the large logo and shows the small one. What you could try is to store if the scroll is more than 0 (meaning that is not at the top) in local/session storage. Then when the page is refreshed you check that if it is, you could set the timeline's progress at 1. Maybe the ideas in these threads could help: Hopefully this helps. Happy Tweening!
  13. Asking the following with a concern for performance, rather than code cleanliness or reusability: Is one better off using a single Scrolltrigger, or multiple, when animating elements across different components, but all on the same page? Some context — I'm using useGSAP in React (Next) to animate a timeline with Scrolltrigger that runs the length of a landing page. The elements animated are contained across several components, representing different sections of the page. On one hand, it is obvious to me that a single Scrolltrigger is less overhead than multiple (less initialization etc.). On the other hand, I'm unsure what GSAP does behind the scenes as far as ignoring out of viewport elements and so on. So - if I am using a single Scrolltrigger (less overhead), could I still be incurring more cost, since GSAP is tracking elements I no longer care about? Am I just better off using multiple Scrolltriggers and aggressively scoping? If anyone has any repos or sandboxes demonstrating suggested patterns that'd be much appreciated. (Hopefully higher level/concept questions are okay - and sorry if this is something touched on already - I tried searching for several minutes but couldn't find anything satisfactorily clarifying. Thanks!)
  14. I have tried this but doesn't seem to work for me. the stack doesn't go behind, it just gets off the stack and hides
  15. Cool thanks, I just found this link in another thread and tried it out in Vue. https://stackblitz.com/edit/vitejs-vite-onqhee?file=src%2FApp.vue&terminal=dev It seems to work in stackblitz, but in my project I cant get horizontal scroll to work... all the panels are stacked vertically instead of 'flex' and i can only scroll vertically. The css and the js is all copied identical. I've also checked the gsap and scrolltrigger are both installed correctly. What typically is the issue when the animations don't work? It seems like gsap isn't working
  16. Hey everyone, I love what you can do with GSAP, but I'm a total newbie and struggling with even horizontal scroll. I tried your demo for vue horizontal scroll, but can't seem to get it work in my vue project. Any advice? Thanks!
  17. Thank you so much for your reply, i solved my issue in this post: but i cannot delete this post
  18. Hi, I'm not really clear on what you're trying to do here, but maybe this video by @Carl could help: Happy Tweening!
  19. Hi, Maybe this demo could help: https://stackblitz.com/edit/github-2hpcon-yct8bb?file=src%2Fcomponents%2FLayout.astro It does uses ScrollSmoother, GSAP's smooth scrolling solution, which is a perk of GSAP Club users: https://gsap.com/docs/v3/Plugins/ScrollSmoother/ https://gsap.com/pricing/ Hopefully this helps. Happy Tweening!
  20. Hi, I believe the issue here is that the trackpad keeps dispatching a wheel event even after the user's interaction with the trackpad has ended. This is not a GSAP related issue, but the way trackpads (and apple magic mouse I believe) works. What you can do is create a safeguard, like a boolean that gets toggled when the wheel event is fired and then toggled back when the animation has completed. Something like this: https://codepen.io/GreenSock/pen/NWVKVwx Hopefully this helps. Happy Tweening!
  21. Hi, Maybe a different logic for every element that is not the first, instead of selecting the ScrollTrigger for the current element and using that start point, use the previous ScrollTrigger (if any) end point: const menuLinks = gsap.utils.toArray("header ul li button"); menuLinks.forEach((elem, i) => { elem.addEventListener("click", function () { let target = elem.getAttribute("data-panel"), trigger = ScrollTrigger.getById(target); if (i > 0) { target = menuLinks[i - 1].getAttribute("data-panel"); trigger = ScrollTrigger.getById(target); } gsap.to(window, { duration: 1, scrollTo: i > 0 ? trigger.end : trigger.start, overwrite: true }); }); }); Hopefully this helps. Happy Tweening!
  22. Hi, Also you can borrow some logic from this demo for the flying flair: https://codepen.io/GreenSock/pen/dywBqWJ Hopefully this helps. Happy Tweening!
  23. Hi, I'm not sure what could be the issue here without a minimal demo, clearly something in the styles you're applying is causing this, because the tailwind styles in Jack's demo are working as expected.
  24. Hi, Maybe something like this: ScrollTrigger.create({ trigger: ".parallax-upper-area", start: "top+=20% top", end: "bottom bottom", endTrigger: ".parallax-below-area", pin: ".parallax-upper-area", pinSpacing: false, markers: true }); Or maybe switch the start to this perhaps: ScrollTrigger.create({ trigger: ".parallax-upper-area", start: "top top+=20%", end: "bottom bottom", endTrigger: ".parallax-below-area", pin: ".parallax-upper-area", pinSpacing: false, markers: true }); Also this could be an option: ScrollTrigger.create({ trigger: ".parallax-upper-area", start: "top+=20% top", end: "+=450", pin: ".parallax-upper-area", pinSpacing: false, markers: true }); Unfortunately the description you provide is not completely clear to me, so I'm taking my best guesses here in terms of what you're trying to do. Hopefully this helps Happy Tweening!
  25. hi @mvaneijgen sorry i should have made it live. kindly find the link attached. https://codesandbox.io/p/live/d420f010-2f4f-456a-bac2-95f22efb5f30
  26. Hi @jaeyholic welcome to the forum! Your codesandbox link is not working, maybe you didn't publish it yet? Personally I like to work in Codepen, just plain HTML, CSS and JS, so that I don't have to worry about my preferred library of choice throwing errors and really can focus on the effect I'm going for, but of course to each their own. The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. It is probably not the effect you're going for, but maybe it points you in the right direction. This one works on click, but could also work on scroll, again everything in GSAP starts with an animation and you can then hook it to what ever you like to play that animation. Hope it helps and happy tweening! https://codepen.io/GreenSock/pen/Yzdzxem
  27. I am new to GSAP and I love it so far. I am working on this project but I am facing an issue now. I want to pin a section, then when scrolling, the stacks on images change, set the currentIndex state with the new index, and update the data on the right side of the section. when the current image, leaves the stack, I want it to go to the back of the stack, and the current image comes on top. I have been struggling to finish it and need some help, please. Codesandbox link: https://codesandbox.io/p/devbox/epic-hill-qgf7r5?file=%2Fsrc%2FApp.jsx%3A111%2C73&workspaceId=832ea3ad-fd7e-4423-a361-77ecef5fb412
  1. Load more activity
×
×
  • Create New...