Jump to content
Search Community

RobbieC

Premium
  • Posts

    106
  • Joined

  • Last visited

Everything posted by RobbieC

  1. Yup everything your saying makes sense. I'm also confused on the server/client components and how they work when "stacking" them, etc... i.e. having a client component with a child component that's a server component. I've asked questions as well in their discord but they don't always get answered. On that note, I'm just testing all of this on a rebuild im working on for my portfolio website, which probably won't be production ready for months, as to why I decided to use it to mess around with the beta app dir. I can be the guinea pig for testing gsap in the new app dir ?
  2. @Rodrigo The example you provided does not work, get a bunch of errors in stackblitz.com But I would have to argue that maybe it shouldn't be directly in the `layout.js` since in your example your turning the `layout.js` into a client component, it may be better to create a `providers.js` file and have the scrollsmoother in there. https://beta.nextjs.org/docs/rendering/server-and-client-components#rendering-third-party-context-providers-in-server-components I updated my codesandbox as an example: https://codesandbox.io/p/github/robbiecren07/nextjs13-gsap/test
  3. Ok so I pieced something together and put it on codesandbox, and after doing so the only issue I really see is that the header animation works on the first initial page that's loaded (so home page or any page you refresh on) but when you switch pages, it does not animate, but the other animations work. I also made a change and wrapped my const instance = ScrollSmoother.create() in a gsap.context() . The public link is: https://codesandbox.io/p/github/robbiecren07/nextjs13-gsap/draft/solitary-darkness Any help with the head component animation would be great, also any feedback on my code would be greatly appreciated! Oh and Happy Holidays GreenSock fam!
  4. Sounds good @Rodrigo! @GreenSock - Ill put together a demo, I just through pieces of my code in here, they are actually pretty large components. I won't be able to make an exact duplicate of my projects but ill put something together. But In my project, the only thing not wrapped in the gsap.context() is this peace of code: const instance = ScrollSmoother.create({ smooth: 1, normalizeScroll: true, ignoreMobileResize: true, effects: true, }) setSmoother(instance) Should that also be inside of gsap.context ?
  5. I hope its ok to ask, I'm looking for someone with some experience in the new Nextjs 13 app directory, using gsap; to hopefully help answer a couple questions I have. I'm not 100% sure it's all directly related to the new app dir system or just the fact that they are different client components. So the first question: In app/layout.js I have a <Header /> client component, in that component I'm using ScrollTrigger to show/hide the navigation bar based on scroll. In app/page.js I'm initializing the ScrollSmoother, so yes my page.js is a client component. In my app/projects/page.js I'm also initializing ScrollSmoother the same way I did in app/page.js. So the SmoothScroller works fine on both pages and during page changes, the issue im running into is that the ScrollTrigger in <Header /> stops working when I change pages. I'm guessing the issue is that on the page change, ScrollTrigger doesn't know what scroller to use because the <Header /> component doesn't change/re-render but the page.js does, almost like it needs to reinitialize when a new page component is rendered. My 2nd question is: Instead of making my page.js a client component, can/should I make a separate client component that initializes the smoothscroller, something like this: // components/SmoothScroller.js 'use client' import { useState } from 'react' import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect' import { gsap } from 'gsap' import { ScrollSmoother } from 'gsap/dist/ScrollSmoother' import { SmootherContext } from '../utils/SmootherContext' export default function SmoothScroller({ children }) { const [smoother, setSmoother] = useState() useIsomorphicLayoutEffect(() => { gsap.registerPlugin(ScrollSmoother) const instance = ScrollSmoother.create({ smooth: 1, normalizeScroll: true, ignoreMobileResize: true, effects: true, }) setSmoother(instance) }, []) return ( <SmootherContext.Provider value={smoother}> <div id="smooth-wrapper"> <div id="smooth-content" className="will-change-transform"> {children} </div> </div> </SmootherContext.Provider> ) } The issue i've run into with using this SmoothScroller component is that when I use it like this on the page: // app/projects/page.js import SmoothScroller from '../../../components/SmoothScroller' import BlockTitle from '../../../components/BlockTitle' export default function Projects() { return ( <SmoothScroller> <section className="w-full py-[18vh] px overflow-hidden"> <BlockTitle title="Projects" /> <div className="container mx-auto"> <div className="flex"> <div className="h-screen"></div> <div className="h-screen"></div> </div> </div> </section> </SmoothScroller> ) } The <BlockTitle> is a client component which is using ScrollTrigger and SplitText, but the scrolltrigger never fires, the markers show up in the correct place and splittext works, its almost like it doesn't know what scroller to attach to. I know I should of created a codesandbox, so I will put one together this evening.
  6. Oh sweet, thanks for the heads up @GreenSock !! On that note, I've read both of the learning gsap in react docs, but are there any other known issues or tweaks that need to be made with gsap when working in react 18? I'm also using Nextjs 13's new experimental app directory, which I'm guessing could bring up some bugs.
  7. @Rodrigo I'm not sure if the codepen you created shows the issue I was having, but I applied your suggestion above: And this fixed the issue I was having. I'm able to do: splitAbout = new SplitText('.about_text', { type: 'lines, chars', linesClass: 's_parent', charsClass: 's_child' }) and it returns correctly, 1 div for the 'lines' and then 1 div for each 'chars'. Thanks!
  8. @GreenSock Jack, can you try that link again? (first time using codesandbox, I forgot to commit the changes). If you go to /app/page.js - you will see gsap.context(), which I have the ctx.revert() - but im guessing that doesn't apply to the splittext within the scope?
  9. I'm new to using gsap in react/nextjs but i've been following the docs and reading some other threads, but I can figure out what's going on with SplitText in my project. Basically I think SplitText is firing twice, all instances of SplitText in my example, you will see that they are wrapped twice in div's created by SplitText. I have not used codesandbox before but I just threw together a quick sandbox which you will be able to see the issue i'm talking about. https://codesandbox.io/p/github/robbiecren07/robbiecrenshaw.dev-nextjs/draft/
  10. Oh, well you do make a good point! I'll have to figure out how to work in your example, cause all of my scrolltriggers/tweens are already nested inside of individual functions, broken down into each section of the page, kind of like: function init() { // code code code // onComplete: () => initContent() } init(); function initContent() { calcStyles(); initIntro(); initProjects(); initClients(); initServices(); initInvest(); initInitiatives(); initCTAs(); initFooter(); } function initIntro() { // all tweens/scrolltriggers for this section // each init function is the same idea }
  11. Thanks Jack! I decided to try something a little different, my project is a little more complex than the example I gave above. This option I feel would work best for my situation, I just declare it at the top of my file: let startPosition; if (window.matchMedia("(max-width: 768px)").matches) { startPosition = 'top 80%'; // mobile } else { startPosition = 'top 60%'; // desktop } Then I just replace 'top 60%' on all my scrolltriggers with startPosition. I haven't fully tested it yet, but we shall see.
  12. I wanted to know if there was a simpler way of adjusting the 'start' position of a scrolltrigger, instead of using ScrollTrigger.mediaMatch and duplicating all the code to only change 1 line. Example: gsap.to(".first", { duration: 1, autoAplha: 1, yPercent: 0, scrollTrigger: { trigger: container, start: "top 60%", end: "bottom bottom", toggleActions: "play none none reverse" } }); So if I wanted to just change "top 60%" to "top 80%" for max-width: 768px. Instead of doing: ScrollTrigger.matchMedia({ // desktop "(min-width: 769px)": function() { gsap.from(".first", { duration: 1, autoAplha: 1, yPercent: 0, scrollTrigger: { trigger: container, start: "top 60%", end: "bottom bottom", toggleActions: "play none none reverse" } }, { // mobile & tablet "(max-width: 768px)": function() { gsap.from(".first", { duration: 1, autoAplha: 1, yPercent: 0, scrollTrigger: { trigger: container, start: "top 80%", end: "bottom bottom", toggleActions: "play none none reverse" } }); It's not bad when its a simple single scrolltrigger, but when I have a project with lots of scrolltriggers and I need to adjust the start position for mobile on all of them, it will be a lot of extra code. Is there simpler/easier way?
  13. Thank you @akapowl !! I initially had my ScrollerProxy set to #viewport BUT I didn't define the scroller for ScrollTrigger, so it wasn't working and when I was searching online I came across an example that had the ScrollerProzy set to document.body and I gave that a try and it seemed to work but as you can see.. it didn't.. ?
  14. First I want to apologize for the amount of code that's in my CodePen, I had to scrap it from my project and make sure I could recreate the issue. In my project I'm using Smooth Scrollbar & Barba.js but I didn't include the Barba code because I was able to recreate the issue without it (plus can you even use barba.js page transitions in codepen?) Anyway the issue I'm having is when you scroll to the end of the page (or to the end of the 2nd pinned section), then resize the window and scroll back up the "portfolio" section is missing. If you inspect element you can see that the "portfolio" section seems like it is still stuck in the pinReparent; which is below all the script tags BUT it doesn't make sense because if you inspect element and watch the two pinReparent's happen; once you get to the end of both sections, the sections leave the pinReparent state but once you resize the window the portfolio section jumps back into the pinReparent state. This issue only happens on a window resize event, so I'm not sure if it's an issue with pinReparent, Smooth Scrollbar or my code. Before I added Smooth Scrollbar to my project I only had the portfolio section and the only way I could get that section to scroll correctly with Smooth Scrollbar was to add the pinReparent. The same goes for when I added the zoom section into the project, it wouldn't work without it. I have tried to add a couple different eventlisteners but that didn't help. Here is the most recent one I tried on my project: let allTriggers = ScrollTrigger.getAll(); ScrollTrigger.addEventListener("refresh", () => bodyScrollBar.update()); ScrollTrigger.refresh(); let progress = 0; ScrollTrigger.addEventListener("refreshInit", () => progress = allTriggers.progress ); ScrollTrigger.addEventListener("refresh", () => allTriggersscroll(progress * ScrollTrigger.maxScroll(window))); bodyScrollBar.addListener(ScrollTrigger.update); I also tried to wrap it in a window.addEventListener and some different variations but no luck. Another weird thing is the word "TEXT" that's in the portfolio section; jumps up once the pin/horizontal scrolling starts. I'm not sure why it does it in the CodePen but is does not do it in my project.
  15. @ZachSaucier Can I ask if there was a particular reason why you used the backtick template literal on the scrolltrigger end property in your codepen above?
  16. Sorry that's because I left .offsetY in the code. I changed it back to the original code: end: () => container.scrollWidth - document.documentElement.clientWidth + container.offsetWidth} Now you should be able to see the issue i'm talking about.
  17. @ZachSaucier Sorry for the delayed reply, did you mean .offsetY? cause it returns NaN. I'm not using jQuery in my project, so I tried .offsetTop but that returns the value from the top of the page to the top the container which is like 15,000px which in return makes the endTrigger value like 17,000px which is way to much.
  18. There is also a few good tutorials/courses that cover smooth scrolling. Here is a few links: https://ihatetomatoes.net/get-bella/ https://www.creativecodingclub.com/courses/scrolltrigger-express I have taken both and they are great, I learned a lot and they both cover smooth scrolling with GSAP and/or a 3rd party library.
  19. I have a question/issue once again on this CodePen: https://codepen.io/robbiecren07/full/QWyKJMg The best way to see the issue im having is to view the pen in Full Page View, I created a spacer that is 900vh (to act like there is a lot of content above the portfolio section), when you scroll down and reach the portfolio section and once the scrolltrigger starts it moves SUPER fast like not even two clicks on the mousewheel and the scrolltrigger end. This shouldn't be happening and I'm not sure why. If you change the spacer-lg from 900vh to 100vh and run the code, you will see that once you get to the portfolio section it moves a lot slower and more natural. The more content/sections I add above the portfolio section, the faster the scrolltrigger moves in the portfolio section, I don't understand why or whats going on. Also on my project I have lots of scrolltriggers but this is the only one that is effected like this, which leads me to believe it has something to do with the the trigger and end trigger. Any input would be much appreciated, Thanks.
  20. I made the CodePen public, sorry about that (I forked one of my own private pens ?). So I did what @Ihatetomatoes suggested and it works! I called my initPortfolioSec() function in the onComplete located inside the initLoader() function and removed it from the function init() list. (Just like the reply above) I updated it in my CodePen.
  21. No worries Jack. I wanted to start the thread before I logged off. I will continue to mess with it and see if I can figure out a solution later this evening.
  22. Good afternoon guys! I came across a little issue on my localhost so I tried to put together a workable Codepen. Basically I have a loader and then the main content in a wrapper in the <main> tag with the class: .is-loading #main_content { display: none; visibility: hidden; } The .is-loading class is on the body tag which I use gsap to remove when loader TL is complete. I know its the display:none that is breaking it because if you remove display:none from that class, the scrolltrigger displays and works correctly. The issue I have with just not having the display:none is that the user can scroll while the loader is playing and then once its complete the user will be somewhere else on the page. I don't want to use a scroll lock hack, so I want to try to use display: none. I'm guessing that I need to recalculate the scrolltrigger or tell it to execute a different way. I have tried using "ScrollTrigger.refresh(true);" a few different ways, but I have had no luck. FYI if you resize the window after the animation is complete, the portfolio section will appear but its broken and the scroll directs gets changed and only 2 images are displayed. Any feedback or guidance would be greatly appreciated.
  23. Thank you @ZachSaucier for the quick reply and the feedback. I will do this moving forward, makes sense and good advise - thank you! So I set width & height and also added the check if images are loaded, like you suggested and it didn't resolve my issue. The images are being loaded at the same time of the first painting. I also added "defer" to both my JS script calls and after checking the "Network" waterfall in Chrome, my images are being loaded fully before the JS file even loads. So I think I ruled out the issue being the images not being fully loaded before the scrolltrigger calculates. As I was typing this reply, I was messing with my JS files trying to debug it and create the issue on codepen, come to find out.... Its the order of my GSAP code in my JS file.... I was calling the ".hr" gsap code before the "portfolio" code... I guess what had me confused is that since i'm using: const line = document.querySelectorAll(".hr"); line.forEach((elem) => { gsap.from(elem, { duration: 1, width: "0", ease: "power3.inOut", scrollTrigger: { markers: true, trigger: elem, start: "top 80%", end: "bottom 10%", toggleActions: "play reverse play reverse" } }) }); and this ".hr" animation is being use in multiple locations on the page, I still need to make sure the order is correct and place it where the last ".hr" is actually being called in the JS file. So for this instant if I use the ".hr" before and after the "portfolio" gsap code, I need to be placing it after the "portfolio" code in the JS file.
  24. @GreenSock I have been messing with the the codepen you created for me above and I ran into a issue when i brought it over to my localhost. Once again i'm having trouble recreating the issue on Codepen so you could see it. I'm like 99% sure it has something to do with the images not being fully loaded before the scrolltrigger calculates. Here is the Codepen I was trying to recreate the issue on: https://codepen.io/robbiecren07/pen/c904f1e5295f3fb1864090bf680603ef I created a animated red line above and below the portfolio section that have markers enabled. On my locahost once I scroll into the portfolio section and the 3rd image starts to come into view, the trigger marker for the bottom red line comes into view and triggers, then once the portfolio section ends all the rest of my scrolltriggerd animations are jacked up. If you notice on the codepen the pin-spacer the height and padding are 5000px+, well on my localhost the pin-spacer height is 2000px and padding 1300px. I have tried wrapping the GSAP code in: function init(){ // GSAP CODE } window.addEventListener('load', function(){ init(); }); I have even tried what Jonathan recommended here: My pin spacer height / padding was still in the 2000px+ range. I also tested it on 3 different browsers and made sure the cache was cleared. I know its hard to debug anything with out a codepen showing the issue. So I will continue working on getting my issue displayed on the codepen. Until then, could you point me to another post or tutorial for integrating a imagesloaded or lazy load with GSAP? I have tried to use the lazyload codepen on the scrolltrigger doc page, I couldn't get it working.
  25. I know this topic is old but I too was having a font rendering issue when using custom fonts. My GSAP code was firing/rendering before my fonts were fully loaded, which caused my splttext to render incorrectly. I'm still testing the solution I found but so far it seems to be working. Here is the solution: function init(){ // my GSAP code } window.addEventListener('load', function(){ init(); }); I discovered this by watching ihatetomates's (Petr Tichy) GSAP tutorials. Right now I've wrapped almost all of my GSAP code in this.
×
×
  • Create New...