Jump to content
Search Community

Search the Community

Showing results for tags 'nuxt'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 23 results

  1. Hello, I am having some troubles making a scrolltrigger animation in a nuxt component. Basically I have a lenis script for a nuxt page and inside this page a scrolltrigger script for the projectItem.vue component. I installed gsap via npm and imported it both in the page and the component. I don't know why but the code seems to work because we enter in the onEnter() callback but there is no animation at all. Here is a link to the stackBlitz of my project, hoping someone can help me : https://stackblitz.com/~/github.com/Mitiss25/portfolioFinal Thank you !
  2. 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(); } }
  3. Hello! I have recently encountered a problem where I am trying to revert the parent divs after a browser resize, but it is not reverting at all! I am trying to revert the "paragraph-" and "headerParentSplit" before the animation starts (as long as it has been set before) I have tried debugging by console logging this if statement, and it does go through, although it still does no difference. First picture with only one header line, is how it should look like. This is what happens when you enter the website with a fullscreen resolution. The other picture with a red and black background for the header, is how it looks like. The reason behind this is that the div is split into lines when the resolution was smaller (therfore it is two divs). It does not revert with the following code.. function setupSplits() { const paragraph = document.querySelectorAll("p"); const header = document.querySelectorAll("h1, h2"); if (headerParentSplit != null) { headerParentSplit.revert(); paragraphParentSplit.revert(); } var headerParentSplit = new $SplitText(header, { // type: "words", linesClass: "split-parent", }); var paragraphParentSplit = new $SplitText(paragraph, { // type: "words", linesClass: "split-parent", }); header.forEach((header) => { // Reset if needed if (header.anim) { header.anim.progress(1).kill(); header.split.revert(); } header.split = new $SplitText(header, { type: "lines,words", linesClass: "split-line", }); // Set up the anim $gsap.set("h1, h2", { visibility: "visible", }); header.anim = $gsap.from(header.split.words, { scrollTrigger: { trigger: header, toggleActions: "restart pause resume reverse", start: "top 95%", }, duration: 0.7, ease: "circ.easeOut", yPercent: 100, opacity: 0, stagger: 0.015, }); }); paragraph.forEach((paragraph) => { // Reset if needed if (paragraph.anim) { paragraph.anim.progress(1).kill(); paragraph.split.revert(); } paragraph.split = new $SplitText(paragraph, { type: "lines,words,chars", linesClass: "split-line", }); $gsap.set("p", { visibility: "visible", }); paragraph.anim = $gsap.from(paragraph.split.words, { scrollTrigger: { trigger: paragraph, toggleActions: "restart pause resume reverse", start: "top 95%", }, duration: 0.6, ease: "circ.easeOut", yPercent: 100, opacity: 0, stagger: 0.005, }); }); } onMounted(() => { setupSplits(); $ScrollTrigger.addEventListener("refresh", () => { setupSplits(); }); });
  4. Hello there, I am fairly new here and would greatly appreciate any help with this issue. I came across this amazing carousel and tried to implement it in my Nuxt project. ( Sample provided in the end ) The same code works on my CodePen but not in my Nuxt project. Here is the code from my CodePen : https://codepen.io/chaowen/pen/GRzrYqB?editors=0011 I also replicated the code in CodeSandbox, which you can find here : https://codesandbox.io/p/sandbox/test-3d-carousel-gsap-26jqsl?file=%2Fpages%2Findex.vue%3A20%2C9 Upon investigation, I realized that the code is not functioning as expected in Nuxt. rotateY: (i) => i * -36 Full code here : let xPos = 0 gsap .timeline() .set('.ring', { rotationY: 180, cursor: 'grab' }) //set initial rotationY so the parallax jump happens off screen .set('.img', { // apply transform rotations to each image rotateY: (i) => i * -36, // !!HERE!! this NOT wokring transformOrigin: '50% 50% 500px', z: -500, backgroundImage: (i) => 'url(https://picsum.photos/id/' + (i + 32) + '/600/400/)', backgroundPosition: (i) => getBgPos(i), backfaceVisibility: 'hidden', }) Any suggestions to resolve this issue? Your help would be greatly appreciated. Thanks a lot.
  5. I'm encountering an issue with my project's GSAP (GreenSock Animation Platform) implementation, specifically related to GSAP's full-page scroll and ScrollTrigger functionalities. Despite having set up the code as per the documentation, it's not working as expected. The issue seems to be affecting the smooth scrolling and trigger animations. I've verified the following aspects: GSAP and ScrollTrigger Plugins: I've ensured that the GSAP and ScrollTrigger plugins are correctly installed and imported in my project. HTML and CSS Structure: I've reviewed the HTML and CSS structure to ensure that it aligns with the required setup for GSAP and ScrollTrigger. Component Import: I've verified that the components referenced in the code are correctly imported and available within the project. ScrollTrigger Triggers: I've set up ScrollTrigger triggers for smooth scrolling and animations for each section, following the documentation. Despite these checks, the issue persists, and I'm encountering errors or unexpected behavior, including difficulties with full-page scrolling and animations not triggering. <template> <div class="content"> <section class="panel"> <HomeBanner /> </section> <section class="panel"> <HomeProductsTabsComponent /> </section> </div> </template> <script> import HomeProductsTabsComponent from '~/components/HomeProductsTabsComponent.vue'; import gsap from 'gsap' import { ScrollTrigger } from 'gsap/ScrollTrigger'; export default { components: { HomeProductsTabsComponent, }, layout: 'default', data() { }, mounted() { // Register GSAP plugins gsap.registerPlugin(ScrollTrigger); // Define sections const sections = gsap.utils.toArray(".panel"); // Function to scroll to a specific section function goToSection(i) { gsap.to(window, .8, { scrollTo: { y: scroll }, ease: Circ.easeOut }, "-=.5"); } // Set ScrollTrigger defaults ScrollTrigger.defaults({ // markers: true }); // Create ScrollTriggers for each section sections.forEach((eachPanel, i) => { ScrollTrigger.create({ trigger: eachPanel, onEnter: () => goToSection(i), }); ScrollTrigger.create({ trigger: eachPanel, start: "bottom bottom", onEnterBack: () => goToSection(i), }); }); }, }; </script> Here the console error: Uncaught TypeError: Failed to execute 'scrollTo' on 'Window': The provided value is not of type 'ScrollToOptions'. at PropTween2._setterFunc2 [as set] (gsap-core.js:3692:25) at PropTween2._renderComplexString2 [as r] (gsap-core.js:3729:8) at Tween2.render3 [as render] (gsap-core.js:3456:12) at Timeline2.render3 [as render] (gsap-core.js:2257:19) at _lazySafeRender2 (gsap-core.js:192:13) at Array.updateRoot (gsap-core.js:2695:7) at _tick2 (gsap-core.js:1315:22) https://codepen.io/sheharzaddev/pen/BaMpKqB I'm seeking advice and solutions from the developer community to help identify and resolve the problem, as the current setup doesn't seem to be achieving the intended scroll and animation effects. If you have any insights or recommendations for troubleshooting and resolving these GSAP and ScrollTrigger issues, your assistance would be greatly appreciated.
  6. <script setup> const { $gsap, $ScrollTrigger, $SplitText, $ScrollSmoother } = useNuxtApp(); function setupSmoothScroll() { $ScrollSmoother.create({ smooth: 1, // how long (in seconds) it takes to "catch up" to the native scroll position effects: true, // looks for data-speed and data-lag attributes on elements smoothTouch: 0.1, // much shorter smoothing time on touch devices (default is NO smoothing on touch devices) }); } function setupSplits() { const paragraph = document.querySelectorAll("p"); const header = document.querySelectorAll("h1, h2"); const parentSplit = new $SplitText(header, { // type: "words", linesClass: "split-parent", }); header.forEach((header) => { // Reset if needed if (header.anim) { header.anim.progress(1).kill(); header.split.revert(); } header.split = new $SplitText(header, { type: "lines,words", linesClass: "split-line", }); // Set up the anim header.anim = $gsap.from(header.split.words, { scrollTrigger: { trigger: header, toggleActions: "restart pause resume reverse", start: "top 120%", }, duration: 0.7, ease: "circ.easeOut", yPercent: 100, opacity: 0, stagger: 0.015, }); }); paragraph.forEach((paragraph) => { // Reset if needed if (paragraph.anim) { paragraph.anim.progress(1).kill(); paragraph.split.revert(); } paragraph.split = new $SplitText(paragraph, { type: "lines,words,chars", linesClass: "split-line", }); // Set up the anim paragraph.anim = $gsap.from(paragraph.split.words, { scrollTrigger: { trigger: paragraph, toggleActions: "restart pause resume reverse", start: "top 120%", }, duration: 0.5, ease: "circ.easeOut", yPercent: 100, opacity: 0, stagger: 0.015, }); }); } onMounted(() => { setupSmoothScroll(); $ScrollTrigger.addEventListener("refresh", setupSplits); setupSplits(); }); const route = useRoute(); watch( () => route.path, () => { $ScrollTrigger.refresh(); } ); </script> I am trying to restart ScrollTrigger when there is a locale change, because otherwise there is no animation for my text when the language is changed. My code where I have done the animations with scrolltrigger (default layout) ^^. I have tried: * Making a watch function for language change and restarting ScrollTrigger(does not work because the text is too quick to change to the other language resulting in the text being static. It does work when I make a timeout, but this results in the text being static for a quick period of time and then the animation begins. * Restarting ScrollTrigger when you press the locale change button (same issue as above) * Scoured the internet and found nothing that would help exactly my situation... Here I have a video where I first show what it should look like, and then what it looks like. Screen Recording 2023-10-11 at 16.00.30.mp4
  7. Hey, i am using Nuxt3 with ScrollSmoother Plugin. So in order to wait until the page is loaded i wait for the mounted event until i show my page like so <template> <div id="smooth-wrapper" v-if="loaded"> <div id="smooth-content"> <Hero /> <Leistungen /> <PortfolioPreview /> <Deutschland style="margin-top: 250px" /> <HorizontalScroll style="margin-top: 250px" /> <Testimotionals /> <References style="margin-top: 150px" /> <Faq style="margin-top: 250px" /> <Footer /> </div> </div> </template> <script setup> import { ScrollSmoother } from "gsap/ScrollSmoother"; import { onMounted, ref } from "vue"; import Hero from "@/components/hero.vue"; import Leistungen from "@/components/leistungen.vue"; import Deutschland from "@/components/deutschland.vue"; import HorizontalScroll from "@/components/horizontalScroll/horizontalScroll.vue"; import Testimotionals from "@/components/testimotionals.vue"; import References from "@/components/references.vue"; import Faq from "@/components/faq.vue"; import PortfolioPreview from "@/components/portfolioPreview.vue"; import Footer from "@/components/footer.vue"; let smoother; const loaded = ref(false); onMounted(() => { console.log("ready"); loaded.value = true; let smoother = ScrollSmoother.create({ smooth: 1, // how long (in seconds) it takes to "catch up" to the native scroll position effects: true, // looks for data-speed and data-lag attributes on elements wrapper: "#smooth-wrapper", content: "#smooth-content", scrub: true, }); }); </script> my problem is, that the scrollsmoother effect doesnt work when i use the v-if statement there. Can someone help me?
  8. Hello, im trying to use SplitText club plugin, but i can't make it work. I've searched in forum but no similar issue found. 1. Club token added to `.npmrc` //npm.greensock.com/:_authToken=xxxxxxx @gsap:registry=https://npm.greensock.com 2. transpile gsap in `nuxt.config.ts` build: { transpile: ['gsap'] } 3. Register plugins in `/plugins/gsap.ts` (this also doesn't work `/plugins/gsap.client.ts`) such as: import gsap from 'gsap' import { ScrollTrigger } from 'gsap/ScrollTrigger' import { SplitText } from 'gsap/SplitText' export default defineNuxtPlugin(() => { gsap.registerPlugin(ScrollTrigger) if (process.client) { gsap.registerPlugin(SplitText) } }) Everthing works fine in local build, but not in actual build on server, this is my error: * Also I find here https://github.com/hypernym-studio/nuxt-gsap/pull/41 this comment: (actually same error using nuxt-gsap) So maybe somehow `gsap/SplitText` is not visible for build ? I tried to make minimal repo, which is oddly working fine (just add authToken to `.npmrc`): https://stackblitz.com/edit/github-fhtp4t-jgbsnt?file=nuxt.config.ts,pages%2Findex.vue,.npmrc
  9. Hi everyone, I'm actually discovering Nuxt 3, and am trying to manage page transitions with GSAP. I'm sorry if my questions also concern Nuxt (and not only GSAP), but I hope to find answers on this forum, which brings together a community of creative people. On the documentation, I saw we can animate page transitions with class names and CSS. But, I'm wondering if a transition manager like Highway exists to use GSAP with my website (e.g. onEnter, onEnterCompleted, onLeave, and onLeaveCompleted functions). My ideal goal would be to animate a page transition and to animate an intro (not the same animation). I do not have a CodePen to share, but here's an illustration of what I'd like to achieve : When the user navigates to the About page, the square goes to position B. And when the user returns to Home, the square goes to position A. References of websites I saw using Nuxt and GSAP (that do not use CSS class names like on the Nuxt documentation) : https://www.heights.agency https://fix.studio https://www.humanastudio.com Thanks for helping… Lucie
  10. Hello everyone, As someone new to GSAP and animation, I am trying to implement this specific animation into my Nuxt.js project. However, I am encountering difficulties and would appreciate any help or guidance you can provide. Here are the dependencies I am currently working with: "nuxt": "^2.15.8" "vue": "^2.7.10" And here are the relevant devDependencies: "nuxt-gsap-module": "^1.7.3" I want to click on the hamburger the menu will open and the hamburger will change to the close button very smoothly same as clicking on the close button. I would like to know how I can successfully implement the menu animation in my Nuxt.js project using these dependencies. Any advice or assistance you can offer would be greatly appreciated. Thank you! reference link: https://www.wilsoncreative.se/
  11. I create a simple demo for this issue. https://stackblitz.com/edit/nuxt-starter-nsqfvz?file=pages/index.vue I use scrollTrigger in gsap.matchMedia(), 1. if I add the "pin" in home page (pages/index.vue), 2. and then go to other pages (pages/page2.vue) 3. resize with different breakpoint it will show this kind of error, Uncaught TypeError: trigger.revert is not a functio After I back to the home page, the scrollTrigger will not work anymore. And seems the scrollTrigger should be killed in "onUnmounted" ? Thank you~~~
  12. Intro: Theres probably not a simple anwser to this but I wanted to see if someone more gsap experienced than me knew of some cool trick that could help me before I go on to do some overly complicated way of solving my issue. Whatver the case, thanks to anyone who is willing to give my issue a shot one way or another. Context: So, I want to create a component builder that lets users drag and drop blocks in place. As part of this I am using GSAP Draggable to drag and drop an element. The riddle im stuck on at the moment is I want the element to snap into place when its dragged over an area that can receive it. The simple solution is to just use the hitTest() function to detect if eligeble element is hit and then get either the points off that element to use in the livesnap, or get the transforms to match that element or something like that. Problem is that in a more complex example, for my use case, I dont actually want to manually create a uniqe function for every possible snappable area since there might be a lot. The ultimate solution would be if I could somehow dynamically fetch whatever snappable element we have hit. But as far as I can tell, from the docs, the hitTest() doesnt actually return the hit element, it just returns a boolean which kinda forces me to do something uniqley for each individual element that can get hit. Question: Is there a straight forward way to dynamically get whatever element I hit with the hitTest()? Codepen: Ive provided a codepen that acts like a massive simplification of what I am trying to do just to narrow it down to exactly what I am asking and making easy to experiement with solutions. Hope that makes it simpler to understand.
  13. Hi ! On my portfolio website that I'm building with Nuxt.js, I want that when the user clicks on a project, the page is scrolled until the top of the project image is aligned with the word "Réalisations" - about 250px from the top of the page. I was inspired by this official gsap example : https://codepen.io/GreenSock/pen/LZOMKY As you can see on my website , when you click on the image and the content is scrolled up, the image does not stop at the right place - but in the opposite direction it works correctly.... any idea what may cause this issue ? Thank you for your help ! ScrollTo script triggered when the user click on a project : scrollToRealisation(event) { let target = event.target.closest(".realisation") this.$gsap.to(window, {duration: 0.5, scrollTo: {y: target, offsetY:250}}); }, Here is the whole code of the page component : <template> <div id="realisations"> <div v-for="item in orderRealisations" :key="item.titre" class="realisation"> <figure @click="scrollToRealisation($event)"> <img :src="require('/assets/imgs/projets/'+item.img)" :alt="item.titre"> </figure> <div class="content"> <div class="contentWrapper"> <header> <h3>{{ item.titre }}</h3> <h5 class="client-year">{{ item.client }} - {{ item.annee }}</h5> </header> <p class="description"> {{ item.description }} </p> <footer> <a class="projectLink" :href="item.url" target="_blank">Consulter le site</a> </footer> </div> </div> </div> </div> </template> <script> import realisationData from '~/static/data.json' export default { name: 'realisations', data() { return { sections: [] } }, asyncData ({ params }) { return { realisationData } }, mounted() { this.sections = this.$gsap.utils.toArray('.realisation'); this.animateOnScroll() }, computed: { orderRealisations() { return this.realisationData.sort((a, b) => b.annee.localeCompare(a.annee)); } }, methods: { //ScrollTo scrollToRealisation(event) { let target = event.target.closest(".realisation") this.$gsap.to(window, {duration: 0.5, scrollTo: {y: target, offsetY:250}}); }, animateOnScroll() { const gsap = this.$gsap this.sections.forEach((section) => { let image = section.getElementsByTagName('figure') let content = section.getElementsByClassName('contentWrapper') this.$ScrollTrigger.saveStyles(".realisation figure, .realisation .contentWrapper"); this.$ScrollTrigger.matchMedia({ "(min-width: 769px)": function() { let imageTl = gsap .timeline({ scrollTrigger: { trigger: section, start: 'top 60%', scrub: 2, end: 'bottom 0px', } }) imageTl.addLabel("animationstart") .to(image, {width: '30vw'}) .to(image, {width: '20vw'}) let contentTl = gsap.timeline({ scrollTrigger: { trigger: section, start: 'top 40%', scrub: false, //in: true, //markers: true, end: 'bottom 35%', toggleActions: "play reverse play reverse" } }) contentTl.addLabel("contentanimation") .fromTo(content, {x:-300, opacity:0,}, {x:0, opacity:1 }, '-=0.8') }, // mobile "(max-width: 768px)": function() { let contentMobileTl = gsap.timeline({ scrollTrigger: { trigger: section, start: 'top 40%', scrub: false, //markers: true, end: 'bottom 35%', toggleActions: "play reverse play reverse" } }) contentMobileTl.addLabel("contentanimation") .fromTo(content, {y:-200, marginTop: 0, height: 0, opacity:0,}, {y:0, height: 'auto',marginTop: 20, marginBottom: 40, opacity:1 }, '-=0.8') } }) }) } } } </script> <style lang="scss"> #realisations { padding-bottom: 60vh; padding-top: 225px; @media all and (max-width: 768px) { padding-top: 0; } .realisation { display: flex; margin-bottom: 3em; @media all and (max-width: 768px) { display: block; flex-direction: column; margin-bottom: 1em; } figure { margin: 0; width: 20vw; cursor: pointer; img { width: 100%; box-shadow: rgba(255, 255, 255, 0.1) 0px 1px 1px 0px inset, rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px; } @media all and (max-width: 768px) { width: 100%; } } .content { max-width: 500px; overflow:hidden; margin-left: 40px; @media all and (max-width: 768px) { margin-left: 0; height: auto; } } .contentWrapper { height: 100%; display: flex; flex-direction: column; justify-content: center; flex-wrap: wrap; header { h3, h5 { margin: 0; } h3 { font-size: 1.4em; margin-bottom: 0em; @media all and (max-width: 768px) { font-size: 1em; } } h5 { font-weight: 400; } } p { font-size: 0.9em; line-height: 1.2; } footer { // margin-top: auto; a { color: #fff; text-decoration: underline; font-size: 0.7em; } } } } } </style>
  14. Selecting a list-item works but doesn’t animate, because GSAP thinks that div._selected has left the DOM as onLeave() indicates. It’s still there, but in a new position. The beforeUpdate() and updated() lifecycle hooks are where I'm getting the state and performing the flip. As an aside, the animation works correctly when the List.vue data changes. ?‍♂️ Any idea how to approach this? --- Places.vue <template> <list> <list-item class="place" v-for="place in places" :key="place.id" @click="selectPlace(place)" :selected="place.id === $store.state.places.selected_record_id"> <div class="name">{{ place.name }}</div> </list-item> </list> </template> <script> export default { name: 'places-page', methods: { selectRecord ({ id }) { this.selected_record = id; } } } </script> ListItem.vue <template> <li class="_item" @click="$emit('click')"> <slot></slot> <!-- This is what moves around --> <div class="_selected" data-flip-id="selected" v-if="selected"> </div> </li> </template> <script> export default { name: 'list-item', props: { selected: { type: Boolean, default: false } } } </script> List.vue <template> <ul class="list-control"> <slot></slot> </ul> </template> <script> export default { name: 'list-control', data () { return { state: null }; }, beforeUpdate () { this.$data.state = Flip.getState(gsap.utils.toArray('.list-control [data-flip-id]')); }, updated () { Flip.from(this.$data.state, { duration: 0.8, ease: 'expo.out', simple: true, nested: true, onEnter: elements => { console.log('*** onEnter', elements); }, // When clicking on an item, this thinks that `div._selected` // has left the DOM and didn’t come back. Seems like // a race condition, but unsure how to proceed since the DOM // should be fully `updated` at this point onLeave: elements => { console.log('*** onLeave', elements); } }); } } </script>
  15. Banging my head a bit. I've got a few Scroll Trigger based animations on the home page of a site and it works flawlessly when in local development. It isn't until we've deployed to a production/staging environment does it break. Effectively what's happening is when we load the site on production/staging all animations run immediately. Not sure if its a component mounting issue (which would mean its not a GSAP issue) or if something is being compiled/computed differently in a live environment? Each section is setup as follows: 1. Define the animation/scroll trigger in the `mount` lifecycle hook 2. Use `$refs` to pass elements into the animation. <template> <div id="vid-container" class="h-screen w-screen bg-white"> <video @loadeddata="loaded" class="w-full fixed inset-0 duration-500 transition-opacity opacity-0" :class="{'opacity-100': videoLoaded}" src="https://player.vimeo.com/external/611257045.hd.mp4?s=785a9d52ed5d188f762436b1bb618493f784d3f5&profile_id=174" autoplay loop muted preload></video> <svg ref="mask" class="mask absolute w-full h-full" > <mask id="mask"> <rect width="100%" height="100%" fill="white"></rect> <text font-family="Bagnard, serif" font-weight="500" x="50%" y="49%" class="origin-center " text-anchor="middle" transform="scale(15)" > <tspan x="50%">Freelance</tspan> <tspan x="50%" dy="1em">Founders</tspan> <tspan style="font-size: .5rem" x="50%" dy="2em"> ↓ </tspan> </text> </mask> <rect id="bg" width="100%" height="100%" fill="#fff"></rect> </svg> </div> </template> <script> import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { CSSRulePlugin } from "gsap/CSSRulePlugin"; if (process.client) { gsap.registerPlugin(ScrollTrigger, CSSRulePlugin); } export default { data() { return { videoLoaded: false, } }, mounted() { console.log('hero mounted') let width = window.innerWidth let speed = 350 //pixels per second let endX = width let duration = endX / speed let ease = "sine.inOut" let intro = ''; if (this.$refs.mask) { this.$nextTick(() => { intro = gsap.timeline({ onComplete: () => {}, scrollTrigger:{ trigger: this.$refs.mask, start: "bottom 100%", end: "bottom 50%", pin: true, scrub: true } }); intro.to(this.$refs.mask, { scale: 5, opacity: 0, duration: 5, ease: ease }, 'intro') } ) } }, methods: { loaded() { this.videoLoaded = true; } } } </script> Staging link example: https://freelance-founders-hgc9zjyrf-progresslabs.vercel.app/ FYI - Working on a minimal example to post here shortly.
  16. Hello, I'm really worried by a problem i have for a gsap scrollTrigger animation i try to implement in a nested Nuxt component. When previewing with markers activated, it appears that the start and end of the trigger are fixed, and not at all near the designated div. Sorry for the tailwind flood in the code - I've already successfully made gsap scrolltrigger animations with tailwind, but it was not in a nested component. I use GSAP with CDN, and scrolltrigger was doing well on other projects. My hypothesis is that the problem is related to a mounting + viewport-height + nested component stuff, but I'm stil lnew to this and i can't understand the problem. In this example, I use refs, but I've already tried a thousand times with a class trigger too (for example, <div class="trigger">) <template> <div ref="trigger" class='w-full h-screen text-black justify-center flex-1 align-middle my-auto relative p-4 pr-8 flex flex-grow bg-white box-border z-5'> <div class="relative flex h-full w-full flex-col"> <div class="flex h-full w-full shadow-inner bg-mastro2 absolute z-5 bg-cover bg-top">huh ?</div> </div> <div ref="carte" class="absolute overflow-scroll flex h-screen justify-end ml-auto "> <div class='p-5 rounded-xl bg-white bg-opacity-70 my-auto mr-10 z-6 flex flex-col w-1/2 justify-center'> <div class='loader_title font-display mb-4 text-gray-700 text-left leading-none text-5xl'>Votre point de départ idéal pour la Côte d'Azur.</div> <div class='loader_legend font-sans text justify'>Lorem ipsum dolor sit amet consectetur adipisicing elit. Titae facere, voluptate vero ea a eius. .</div> <div class='loader_button mt-4 '><button @click="carta()" class="bg-opacity-50 hover:bg-opacity-100 border border-black p-3 w-32 text-center outline-none text-black bg-white">RESERVER</button></div> </div> </div> </div> </template> <script> export default { mounted() { const { trigger, carte } = this.$refs let hero_scroll = gsap.timeline({ scrollTrigger: { trigger: trigger, start: 'top center', end: 'bottom center', markers:true, scrub: true, } }) .to(carte, { x: -200, duration:3 }).reverse() }} </script>
  17. It appears as though the scrollerProxy is initiated multiple times after routing which causes the matrix 3d animation to jump from -232213 to 0 and back. I think this is because the nuxt instance is kept while routing between pages that also use the _.vue page template but I cant figure out how to force it to forget the past scrollerProxy ? Any advice as to how to initiate smoothscrolling in Nuxt? // _.vue template <template> <div> </div> </template> <script> import { gsap } from 'gsap' import { ScrollTrigger } from 'gsap/ScrollTrigger' gsap.registerPlugin(ScrollTrigger) export default { mounted() { this.smooth() this.$forceUpdate() }, destroyed() { // used to kill the ScrollTrigger instance for this component this.expand = false }, methods: { smooth() { if (process.client) { window.scrollTo(0,0) const locoScroll = new this.LocomotiveScroll({ el: document.querySelector('.smooth-scroll'), smooth: true }) // each time Locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning) locoScroll.on('scroll', ScrollTrigger.update) ScrollTrigger.scrollerProxy('.smooth-scroll', { scrollTop(value) { return arguments.length ? locoScroll.scrollTo(value, 0, 0) : locoScroll.scroll.instance.scroll.y }, // we don't have to define a scrollLeft because we're only scrolling vertically. getBoundingClientRect() { return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight} }, // LocomotiveScroll handles things completely differently on mobile devices - it doesn't even transform the container at all! So to get the correct behavior and avoid jitters, we should pin things with position: fixed on mobile. We sense it by checking to see if there's a transform applied to the container (the LocomotiveScroll-controlled element). pinType: document.querySelector('.smooth-scroll').style.transform ? 'transform' : 'fixed' }) // each time the window updates, we should refresh ScrollTrigger and then update LocomotiveScroll. ScrollTrigger.addEventListener('refresh', () => locoScroll.update()) // after everything is set up, refresh() ScrollTrigger and update LocomotiveScroll because padding may have been added for pinning, etc. ScrollTrigger.refresh() const headerItems = ['.header__logo', '.nav', '.header__trigger'] if (!this.isTouchDevice()) { headerItems.forEach((item) => { gsap.to(item, { scrollTrigger: { trigger: '.header', scroller: '.smooth-scroll', scrub: true, pin: true, start: 'top', end: document.querySelector('body').offsetHeight, pinSpacing: false, }, y: document.querySelector('body').offsetHeight, transformOrigin: 'center top', ease: 'none' }) }) const largeMedia = document.querySelectorAll('.large-media.no-controls') if (largeMedia) { largeMedia.forEach((media) => { let mediaItem = media.querySelector('video') if (media.querySelector('img')) { mediaItem = media.querySelector('img') } gsap.to(mediaItem, { scrollTrigger: { trigger: media, scroller: '.smooth-scroll', scrub: true, start: 'top', end: 'bottom', }, y: '100%', transformOrigin: 'center top', ease: 'none' }) }) } const nextCase = document.querySelector('.next-case') if (nextCase) { gsap.to('.next-case .large-media', { scale: 1, opacity: 0, scrollTrigger: { trigger: nextCase, scroller: '.smooth-scroll', start: `top-=${window.innerHeight / 2}`, end: `bottom-=${window.innerHeight}`, scrub: 1, } }) gsap.to('.next-case__background', { opacity: 1, scrollTrigger: { trigger: nextCase, scroller: '.smooth-scroll', start: `top-=${window.innerHeight / 2}`, end: `bottom-=${window.innerHeight}`, scrub: 1, } }) gsap.to('.large-text-header', { opacity: 1, scrollTrigger: { trigger: nextCase, scroller: '.smooth-scroll', start: `top-=${window.innerHeight / 2}`, end: `bottom-=${window.innerHeight}`, scrub: 1, } }) const observerTrigger = document.querySelector('.next-case__observer-trigger') const onIntersection = (entries) => { for (const entry of entries) { if (entry.isIntersecting) { this.loaded = entry.intersectionRatio if (entry.intersectionRatio > 0.95) { this.background = true if (!this.expand) { // window.location.href = nextCase.querySelector('a').getAttribute('href') // goor, doch effectief this.$router.push(nextCase.querySelector('a').getAttribute('href')) this.expand = true } } } } } let threshold = [] // create array with numbers between 0 and 1 for (var i = 0; i <= 100; i++) { threshold.push(i / 100) } const observer = new IntersectionObserver(onIntersection, { threshold }) observer.observe(observerTrigger) } } } }, isTouchDevice() { try { document.createEvent('TouchEvent') return true } catch (e) { return false } } }, } </script>
  18. Hi people, Anybody have problem with Nuxt, Vuetify and ScrollTrigger - wrong start position for trigger? Start is set to "top top" but with markers: true I see that start is above trigger div element with a value that depends on width of page. As trigger div element is positioned lower on page, gap is getting bigger. Same code works fine in Vue. Even most simple ScrollTriger example behaves same in Nuxt - start is above trigger element (if trigger div is in the middle of page, not top). I think that this probelm have something to do with Nuxt server side rendering, but not sure. I tried to wrap everything in if (process.client) { ... } but no success. Anybody have similar problems or idea? Thanks, gmilic
  19. Hi again. I'm having an issue I can't seem to go around... In Nuxt, I'm using ScrollTrigger.create to pin to specified panels on a index.vue page. All is fine. When navigating to other pages (with or without ScrollTriger animations), the new page is still running the ScrollTrigger, thus pinning to the index.vue instructions, even though its a totally diferent page. My initial thought was to do 'ScrollTrigger.kill()' on the lifecycle 'beforeDestroy()', which works... until I come back to the index page to see there's no animation anymore... I can't do it in codepen (don't know how to do Nuxt there), but I've prepared a codesandbox.io. https://codesandbox.io/s/unruffled-antonelli-dl8fw In summary: If I don't do ScrollTrigger.kill(), the next pages still run to the current ScrollTrigger animation (next pages become unusable) If I do ScrollTrigger.kill() when the current page is destroyed, the next pages are correct. But when navigating again to the initial one, there's no more animation. Any ideas?
  20. Sorry for the noob question here, but I can't seem find it anywhere, so here goes. My nuxt.js index page has several 'panel' components. Each one is full page, and are animated like on this codepen. https://codepen.io/urbgimtam/pen/XWXdypQ Because I'm working with Nuxt, on the main page (responsible for animating the 'panels') I'm using something like: <template> <div> <panel :content="content_a" /> <panel :content="content_b" /> <panel :content="content_c" /> </div> </template> <script> import { gsap, ScrollTrigger } from 'gsap/all' import panel from '[path/to/component]' export default { components: { panel }, data() { return { tl = gsap.timeline() } }, mounted() { gsap.registerPlugin(ScrollTrigger) [... animations defined here ] }, methods: { playAnim() { this.tl.play(0) } } } </script> However, inside each <panel>, I also want to have independent animations. If inside a <panel> component I have again <script> import {gsap, ScrollTrigger} from 'gsap/all export default { data() { panelTimeline: gsap.timeline() }, mounted() { gsap.registerPlugin(ScrollTrigger) [... animations defined here] }, methods: { playAnim() { this.panelTimeline.play(0) } } } </script> is the panelTimeline refering to the same timeline as the parent? I seem to have some interference somewhere in my project and I'm wondering if the parent component ends up sharing the same timeline as the children. I'm using ScrollTrigger on the index (which is the parent of all the panel components), and I've read on the Docs that it uses one single timeline. If so, what should be the best way to make sure to have independent timelines? Big thank you in advance. PS: On gsap v.2, we would do tl: new Timeline() and that would work (and there was no ScrollTrigger )
  21. Hello everyone, i just started using the Club Greensock Plugins with Nuxt.js and quickly faced the problem of importing them using the ES6 import syntax. I have tried multiple methods to get it working, but all i get is the error "Cannot read property 'middleware' of undefined" after importing it in my component with "import 'gsap/DrawSVGPlugin'". Importing TimelineMax works. The same happens when using a private git repo like described here: All the files from the Club Download's "bonus-files-for-npm-users" folder are in the root of the gsap package downloaded from npm, with a custom package.json like described in the post above. Thanks in advance
  22. Hi, is there a way to use the gsap Draggable in Nuxt.js? I get the error "navigator is not defined" in file "node_modules\gsap\Draggable.js" line 391 _isIE10orBelow = (((/MSIE ([0-9]{1,}[\.0-9]{0,})/).exec(navigator.userAgent) || (/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/).exec(navigator.userAgent)) && parseFloat( RegExp.$1 ) < 11), //Ideally we'd avoid user agent sniffing, but there doesn't seem to be a way to feature-detect and sense a border-related bug that only affects IE10 and IE9. I am referencing gsap and Draggable inside my .vue file by: import TweenMax from 'gsap' import Draggable from 'gsap/Draggable' I am guessing this is due to Nuxt doing a server side render and not having a window/navigator object?
  23. Hi, all. When I try to import the DrawSVGPlugin to a NuxtJS project, I get the following error: TypeError: Cannot read property 'defaultView' of undefined at /Users/mdf/Sites/nuxtproject/node_modules/gsap/DrawSVGPlugin.js:19:27 at Object.<anonymous> (/Users/mdf/Sites/nuxtproject/node_modules/gsap/DrawSVGPlugin.js:202:54) at Module._compile (module.js:569:30) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:503:32) at tryModuleLoad (module.js:466:12) at Function.Module._load (module.js:458:3) at Module.require (module.js:513:17) at require (internal/module.js:11:18) at r (/Users/mdf/Sites/nuxtproject/node_modules/vue-server-renderer/build.js:5812:16) at Object.<anonymous> (webpack:/external "gsap/DrawSVGPlugin":1:0) at __webpack_require__ (webpack:/webpack/bootstrap 8aad739dc52752aa5015:25:0) at Object.70 (2.server-bundle.js:123:77) at __webpack_require__ (webpack:/webpack/bootstrap 8aad739dc52752aa5015:25:0) at Object.61 (pages/index.vue:7:0) at __webpack_require__ (webpack:/webpack/bootstrap 8aad739dc52752aa5015:25:0) The error is related to the call to `_doc.defaultView` and only happens when the page is server rendered, not when it is client rendered. I'm not sure if there is an issue with the vue-server-renderer package or if I'm not importing the plugin correctly. I've tried importing the plugin from the assets folder import TweenLite from 'gsap'; import '~/assets/DrawSVGPlugin'; as well as copying it into the gsap folder in node_modules import TweenLite from 'gsap'; import 'gsap/DrawSVGPlugin'; Both produce the same error. The error is also not Nuxt-specific but happens whenever Vue server-side rendering is used. I put together a bare-bones example to illustrate the problem here https://github.com/michaeldfoley/vue-ssr-drawsvgplugin-error. Any help would be appreciated.
×
×
  • Create New...