Skrypt Posted November 30, 2021 Share Posted November 30, 2021 Hi everyone, I'm working on my first Nuxt 3 website with GSAP and ScrollTrigger, however I can't get things to work as I want. First of all, there's a minimal demo over here: https://codesandbox.io/s/skrypt-nuxt-dev-cvw0o (codesandbox instead of CodePen, so everything is fully loaded). The problem: When you load the homepage, you can see the markers of the ScrollTriggers. These ScrollTriggers are initialized inside each component (./components/sections). The components are loaded dynamically on the website. When going to another page (e.g. /over-ons) and navigating back to the home page, you can see the Start marker has move to the top of the viewport. This causes the timeline in the second component to start playing while the ScrollTrigger shouldn't have fired yet. I know I have to kill the ScrollTriggers before the new components are being loaded, but none of the lifecycle hooks seem to work. I've tried this inside the pages/[...slug].vue and pages/index.vue files like this: import { ScrollTrigger } from "gsap/ScrollTrigger" export default { async beforeMount() { ScrollTrigger.getAll().forEach(ST => ST.kill()) ScrollTrigger.refresh() }, } I guess the problem has to do with Nuxt 3 or with my way of dynamically loading the components (they're first fetched from the CMS, then loaded inside Nuxt). The weird thing is, if I add a setTimeout() to the mounted() hooks to delay the GSAP code, the ScrollTriggers do work as expected. Anyone who can help me work around this issue? Link to comment Share on other sites More sharing options...
Cassie Posted November 30, 2021 Share Posted November 30, 2021 Hey there! Dropping these links here in case they help. If you don't manage to find the answer here maybe chat to the nuxt community about the right approach - it sounds like you'll get more benefit from someone with a deep understanding of Nuxt's lifecycle hooks than GSAP. 1 Link to comment Share on other sites More sharing options...
Skrypt Posted November 30, 2021 Author Share Posted November 30, 2021 @Cassie thanks for your reply! Unfortunately, the links you dropped don't contain the solution. I've currently implemented a setTimeout() of 250ms and the issue seems to be gone. Also dropped the question in the Nuxt discord, maybe someone over there can point me in the right direction. 2 Link to comment Share on other sites More sharing options...
Luca Argentieri Posted July 28, 2022 Share Posted July 28, 2022 On 11/30/2021 at 2:50 PM, Skrypt said: @Cassie thanks for your reply! Unfortunately, the links you dropped don't contain the solution. I've currently implemented a setTimeout() of 250ms and the issue seems to be gone. Also dropped the question in the Nuxt discord, maybe someone over there can point me in the right direction. Hey @Skrypt, can you share new solutions from Discord? Of course if you have it. Link to comment Share on other sites More sharing options...
Michael Precel Posted August 29, 2022 Share Posted August 29, 2022 Hi @Skrypt — I've got an implementation working when navigating across pages — you have to declare the animation in the script setup, not bound to a ref, and then activate it on the onMounted hook, eg <script setup> import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); const animation = gsap.timeline({ scrollTrigger: { start: "top top", end: "center top", scrub: 1, }, }); const logo = ref(null); onMounted(() => { animation.to(logo.value, { yPercent: -100, opacity: 0, duration: 1 }); }); </script> 1 Link to comment Share on other sites More sharing options...
kgs-kt Posted December 26, 2022 Share Posted December 26, 2022 (I am a Japanese speaker, translated by deepl.) We have confirmed a bug in the execution of ScrollTrigger when pageTransition is set. My solution is one of the following. 1、Do not use pageTransition. 2、Delay the execution of the ScrollTrigger in onMounted longer than the time required for the pageTransition (use setTimeout). 3、Set page-key in the NuxtPage component in app.vue. 4、Set definePageMeta key in each page component. -- postscript -- However, I found that changing the page-key using methods 3 and 4 causes another problem with the pageTransition. I just found another solution! 5. create plugins and use Nuxt's 'page:transition:finish' hook. Link to comment Share on other sites More sharing options...
GSAP Helper Posted December 26, 2022 Share Posted December 26, 2022 It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? It sounds like maybe you're loading ScrollTrigger dynamically, so the normal "DOMContentLoaded" and "load" events aren't being dispatched by the browser, thus ScrollTrigger has no idea that it needs to refresh(). I'm totally guessing here. Have you tried running ScrollTrigger.refresh() when you know that the DOM/layout has settled? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer. Here's a Nuxt starter template. 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...
svenilla Posted January 3, 2023 Share Posted January 3, 2023 If you reload the ScrollTrigger page in your GSAP & Nuxt 3 Starter, the page no longer works. Link to comment Share on other sites More sharing options...
GSAP Helper Posted January 3, 2023 Share Posted January 3, 2023 Hi there @svenilla. Can you be a bit more specific please? I can't seem to replicate the problem. Do I just need to go to that StackBlitz page and click the "reload" button in the results section? Or reload the entire browser? What steps can I take and what exactly breaks? The more details, the better. Link to comment Share on other sites More sharing options...
svenilla Posted January 3, 2023 Share Posted January 3, 2023 Thanks for your feedback. Yes, to see the error, all you have to do is click "reload" on the ScrollTrigger page in the results section. The LayerSection page has the problem too. As you can see also on this screenshot, the script is not interpreted after the reload. Link to comment Share on other sites More sharing options...
svenilla Posted January 3, 2023 Share Posted January 3, 2023 Sorry, I have to correct myself, the LayerSection page has the problem too. Link to comment Share on other sites More sharing options...
Rodrigo Posted January 3, 2023 Share Posted January 3, 2023 @svenilla thanks for reporting! Happy Tweening! 1 1 Link to comment Share on other sites More sharing options...
svenilla Posted January 4, 2023 Share Posted January 4, 2023 Great, thank you very much! What was the problem? Link to comment Share on other sites More sharing options...
svenilla Posted January 4, 2023 Share Posted January 4, 2023 My goal is to use ScrollTrigger to animate elements on entering page. When I navigate to another page I want to animate the elements off to get a nice page transition. So, when I enable pageTransition in nuxt.config.ts in your GSAP & Nuxt 3 Starter and navigate through the pages, the scripts don't work anymore. export default defineNuxtConfig({ app: { pageTransition: { name: 'page', mode: 'out-in' } }, }) Do you have a solution for this or an alternative to get the desired behaviour? Link to comment Share on other sites More sharing options...
Rodrigo Posted January 4, 2023 Share Posted January 4, 2023 7 hours ago, svenilla said: Great, thank you very much! What was the problem? Just some small issues in the HTML that caused Vue to not render the styles properly until a route change. In terms of that I'm working on a page transitions example using Nuxt3 so please stand by and as soon as it's live I'll get back to you on this thread. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
svenilla Posted January 5, 2023 Share Posted January 5, 2023 Super, thank you @Rodrigo! I am very curious about your new example. Link to comment Share on other sites More sharing options...
Rodrigo Posted January 6, 2023 Share Posted January 6, 2023 Hi, Here is the example for page transitions in Nuxt3: https://stackblitz.com/edit/nuxt-starter-bthjlg As you can see it follows the same pattern as this example in Vue3: https://stackblitz.com/edit/vitejs-vite-w8wtpj The only difference is that in Vue we have a top level file (App.vue) where we setup all our transition code for the entire app. In the case of Nuxt there is not such option as we have to configure it on each page using the definePageMeta global method. In order to not repeat the same code over and over I came up with the helper file that has all the configuration and that uses the transition composable, which keeps pages files small and nice, at least in that particular aspect. The transition purposely affects the position of the page container on the Y axis as well as it's scale, in order to require the animation to be completed to create the ScrollTrigger instances, so everyone can see that particular pattern. Of course if your transitions don't change any of that there shouldn't be needed, but just in case is a good idea to have it there so everyone can see the best possible approach. Finally if someone has an idea to better improve this or any other example, we're all ears as we look forward from your inputs and ways to make things as good as possible. Hopefully these are helpful and let us know if you have any comments, questions or issues. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
svenilla Posted January 6, 2023 Share Posted January 6, 2023 Nice, thank you! But as soon as I refresh the page Scrolltrigger or the page LayersSection, the tweening is no longer executed (The problem we've had before). This occurs in both versions. Link to comment Share on other sites More sharing options...
Rodrigo Posted January 6, 2023 Share Posted January 6, 2023 3 hours ago, svenilla said: But as soon as I refresh the page Scrolltrigger or the page LayersSection, the tweening is no longer executed (The problem we've had before). This occurs in both versions. Hey @svenilla, thanks for reporting (again 😆)! So the issue is that the state is being updated only on the transition and not when the page is loaded for those routes. The solution is different in Vue and Nuxt, because Nuxt uses <suspense> for routing so when the app.vue file is mounted the state changes but the page/view component is not rendered yet, so when it renders the watcher doesn't trigger. Since Nuxt uses suspense, when the component renders the watcher will be ran again but in Vue that doesn't happen, that's why we have to add the immediate flag in the watch hook: watch( [() => transitionState.transitionComplete, main], (newValue) => { if (newValue && main.value) { ctx.value = gsap.context((self) => { const boxes = self.selector(".box"); boxes.forEach((box) => { gsap.to(box, { x: 150, scrollTrigger: { trigger: box, start: "bottom bottom", end: "top 20%", scrub: true, }, }); }); }, main.value); // <- Scope! } }, { immediate: true, } ); That forces the execution of the watcher hook when the component is created. That brings another issue though that the ref is not yet available, so we have to watch that as well. Hopefully this works as expected. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
svenilla Posted January 9, 2023 Share Posted January 9, 2023 Thank you very much @Rodrigo, now the reloading works. However, when I navigate forwards or backwards via the browser, the progress of the animation and the scroll position are always reset, which is bad for usability. What would you have to change if you want to keep the status and scroll position when changing pages. Link to comment Share on other sites More sharing options...
svenilla Posted January 12, 2023 Share Posted January 12, 2023 Hi @Rodrigo, can you please tell me if you think it is possible to use scrollTrigger and page transitions in nuxt3 so that the scroll position is preserved when navigating the pages? Link to comment Share on other sites More sharing options...
Rodrigo Posted January 12, 2023 Share Posted January 12, 2023 Hi, Yeah it should be possible using scroll restoration: https://developer.mozilla.org/en-US/docs/Web/API/History/scrollRestoration Or perhaps local storage to keep track of it: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage https://developer.mozilla.org/en-US/docs/Web/API/Storage Or perhaps tinker with Nuxt Router's configuration: https://github.com/nuxt/nuxt.js/issues/3471 Although I don't know how feasible the last option is in Nuxt3, you'll have to check the docs and ask in their discord channel: https://discord.com/channels/473401852243869706/ Unfortunately I haven't had time to circle back to this yet, so hopefully you'll be able to make some progress. Let us know how it goes and if you have any questions. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
Alleen Posted February 24, 2023 Share Posted February 24, 2023 Hey @Rodrigo, First of all I want to thank you for sharing an example how to use GSAP with Nuxt 3. Just as Svenilla I'm trying to use Scroll Trigger, but seem to have mount / unmount issues when page transition is enabled. I've tried to use the same set-up as the example project above and I get a different issue, but perhaps they are related to what I am having now in my own project. When using page transitions (enabling it in the nuxt.config.ts) with same basic fade effect will result into an error and/or not playing the scroll animation: URL: https://stackblitz.com/edit/nuxt-starter-mvowjp?file=pages%2Fscroll.vue,nuxt.config.ts app.vue <template> <Header /> <NuxtPage /> </template> <style> .page-enter-active, .page-leave-active { transition: all 0.2s; } .page-enter-from, .page-leave-to { opacity: 0; filter: opacity(50%); } </style> nuxt.config.ts // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ app: { pageTransition: { name: 'page', mode: 'out-in' }, }, css: ['@/assets/styles.css'], build: { transpile: ['gsap'], }, }); Also I noticed if you navigate really fast between the tabs it also breaks the animation and the website stops working. Link to comment Share on other sites More sharing options...
Rodrigo Posted February 24, 2023 Share Posted February 24, 2023 Hey @Alleen and welcome to the GreenSock forums! I noticed a few things. First you're using CSS Transitions. Since I've been using GSAP for so many years I never ventured into using CSS for page transitions in Vue/Nuxt, so I can't give you much assistance with that aspect. Also in your Scroll page you have several children at the root level of the template. While this is no problem for Vue3, the Transition component does requires only one children so that is causing an issue. Also when navigating to the layers page, it seems that the ScrollTrigger instances are being created before the page is completely rendered. As I mentioned I've never used CSS for page transitions so this are somehow uncharted waters for me. We built this starter template that uses GSAP for page transitions that has been tested and seems to work as expected: https://stackblitz.com/edit/nuxt-starter-bthjlg?file=helpers%2FtransitionConfig.js In that particular file you'll find the configuration for the page transitions that you can tinker with in order to use fade in/out in your project. Hopefully this helps. Let us know if you have more questions. Happy Tweening! Link to comment Share on other sites More sharing options...
Alleen Posted February 25, 2023 Share Posted February 25, 2023 Dear @Rodrigo, Thank you for the tips and example. I have moved away from CSS animations and now the timing seems to be better, but while navigating through the pages it appears that the scroll position is not correctly calculated. It jumps or simply won't start the animation at all. I will try to create a simple version in StackBlitz out of the actual project I'm working on. Hopefully you'll have the time to help me out with this. EDIT: A sample example of what I think I'm experiencing in my project: https://stackblitz.com/edit/nuxt-starter-tx3skg?file=pages%2Fscroll.vue When refreshing the page on the "Scroll Trigger" tab it works as expected, but when navigating from "Layers Section" back to "ScrollTrigger", you'll notice that the animation is not working properly anymore. In my project the translation jumps from `translate3d(-120px, 0px, 0px)` to `translate3d(2px, 0px, 0px)`. Have an awesome evening! 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