Share Posted April 14, 2022 For those looking to integrate ScrollSmoother with Nuxt, here's a solution that builds off some of the work by @Born05 in this thread. CodeSandbox: https://codesandbox.io/s/gsap-scrollsmoother-nuxt-pbhmeh?file=/layouts/default.vue All you have to do is include the GSAPScrollSmoother and put whatever content you want inside of this. <GSAPScrollSmoother :vars="{ smooth: 2, effects: true }"> <Nuxt /> </GSAPScrollSmoother> You'll be able to access the ScrollSmoother in any page/component using this.$scrollSmoother, and can use any of the methods available, for example. this.$scrollSmoother.paused(true); let velocity = this.$scrollSmoother.getVelocity(); There are also a couple of extra methods available. $scrollSmoother.parseEffects() Call this to get ScrollTrigger to parse and create effects that are declared with data attributes, (data-speed and data-lag). $scrollSmoother.killEffects() Call this to kill all the ScrollSmoother effects. You will typically need to call this when navigating to a new page. $scrollSmoother.refresh() Refresh the ScrollSmoother and all ScrollTriggers. You should call this when navigating to a new page if you don't call .parseEffects() There are really only 2 files you need to be concerned about. The GSAPScrollSmoother.vue component file, and the nuxt.config.js file. The nuxt.config.js has some pageTransition callbacks in there that you may need to adjust to your project. And if you plan on using this in your own project, be sure to change all the gsap-trial imports to gsap, otherwise you won't be able to deploy it. Example usage on a page... export default { mounted() { // if you don't have any effects, use this.$scrollSmoother.refresh() instead this.$scrollSmoother.parseEffects(); this.myAnimation = gsap.timeline({ scrollTrigger: { ... } }) }, beforeDestroy() { // kill any ScrollTriggers you created this.myAnimation.scrollTrigger.kill(); // kill the effects that were created this.$scrollSmoother.killEffects(); } } 7 Link to comment Share on other sites More sharing options...
Share Posted January 15 Hello! Thanks for the great solution, it has saved me a lot of time. Everything worked perfectly until I created multiple layouts, it took me a while until i got a positive result. At the end i recreated the ScrollSmoother on the layout change in every layout . mounted() { this.$scrollSmoother.create(); }, beforeDestroy() { this.$scrollSmoother.kill(); }, https://codesandbox.io/s/sad-bhaskara-tl1ds2 If there is a better way, please correct me, if not i hope it will save some time for others. Link to comment Share on other sites More sharing options...
Share Posted January 18 Hi @Fisher666, Indeed re-creating the Smoother instance on every route is a good way to have everything working as expected. I'll create an example that uses a layout for the pages (a common scenario in Nuxt needless to say) to do that. Is worth noticing that your example uses the ScrollSmoother wrapper created by @OSUblake for Nuxt2. Right now we're moving towards Nuxt3, so the setup I'll create will use that particular version with the Composition API as well but it won't create and use a ScrollSmoother wrapper. Please stand by for that example. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
Share Posted February 27 @Rodrigo any update on this? I'm currently using Nuxt3 and I'm wondering if anyone has come up with a better/smarter approach than me, creating and destroying the ScrollSmoother using client-side life-cycle hooks. Having a lot of pages, my approach works, but gets very verbose and does not feel right. Link to comment Share on other sites More sharing options...
Share Posted February 27 Hi @bennyzen and welcome to the GreenSock forums! First thanks for being a Club GreenSock member and supporting GreenSock! Unfortunately no update yet. I'll try to get something working this week using the layout approach, but in the mean time killing/creating the ScrollSmoother instance using life cycle hooks should be good enough. 4 hours ago, bennyzen said: Having a lot of pages, my approach works, but gets very verbose and does not feel right. Yeah, it gets repetitive to create the ScrollSmoother instance on each page by hand, but in no way I'd get the feeling that is not right. Repetitive maybe, but not right? It might not look elegant but that's another thing. In the mean time you could extract everything into a single method and import it on your pages: // helpers/createSmoother.js const createSmoother = (config) => { const smoother = ScrollSmoother.create({ smooth: 1, effects: true, ...config // add extra config if you use different ones for each page }); }; Then in your pages: import createSmoother from "@/helpers/createSmoother"; let ctx, smoother; onMounted(() => { smoother = createSmoother(); }); onUnmounted(() => { ctx.revert(); }); That should take some of the repetitiveness away for a while Hopefully this helps. Happy Tweening! 1 Link to comment Share on other sites More sharing options...
Share Posted February 28 @Rodrigo many thanks for your quick reply. And yes, your approach is more elegant than mine. Allowing to pass in some more config options on a per page basis with the spread is a cool idea. Borrowed! I just put the helper method into the plugin file itself ~/plugins/gsap.client.js import { gsap } from 'gsap' import { ScrollToPlugin } from 'gsap/ScrollToPlugin' import ScrollTrigger from 'gsap/ScrollTrigger' import ScrollSmoother from 'gsap/ScrollSmoother' // import { Draggable } from 'gsap/Draggable' // import GSDevTools from 'gsap/GSDevTools' // import TextPlugin from 'gsap/TextPlugin' // import SplitText from 'gsap/SplitText' gsap.registerPlugin( ScrollToPlugin, // Draggable, // GSDevTools, ScrollSmoother, // TextPlugin, // SplitText, ScrollTrigger ) const initScrollSmoother = () => { const sm = ScrollSmoother.create({ effects: true, overshoot: 0.1, smooth: 1, smoothTouch: 0.1, speed: 2.0, }) return sm } export default defineNuxtPlugin(() => { return { provide: { gsap, ScrollToPlugin, ScrollTrigger, ScrollSmoother, initScrollSmoother, // Draggable, // GSDevTools, // SplitText, }, } }) and used something like const { $initScrollSmoother, $gsap, $ScrollTrigger } = useNuxtApp() let sm onMounted(() => { sm = $initScrollSmoother() }) onUnmounted(() => { sm ? sm.kill() : null }) on every page where it is needed. One thing that I'm still struggling with is when triggering the navigation using the router directly (per code), the instance does not seem to get killed reliably. But I need to further investigate it or just add some more life-cycle hooks to make sure it really gets killed. 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