Share Posted May 11, 2022 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 : 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> See the Pen LZOMKY by GreenSock (@GreenSock) on CodePen Link to comment Share on other sites More sharing options...
Share Posted May 11, 2022 Welcome to the forums @jeromebart It's hard to offer any advice without seeing a minimal demo. You can use CodeSandbox for nuxt. https://codesandbox.io/s/gsap-nuxt-starter-r5lkg?file=/pages/index.vue Please only include relevant code that is needed to reproduce the issue. Link to comment Share on other sites More sharing options...
Author Share Posted May 12, 2022 Hi, you can see the problem on this link https://bart-studio.ch/inprogress/realisations/ that I provided above, but I will try to make a demo on sandbox. 1 Link to comment Share on other sites More sharing options...
Share Posted May 12, 2022 3 hours ago, jeromebart said: Hi, you can see the problem on this link https://bart-studio.ch/inprogress/realisations/ that I provided above I don't even know what I'm supposed to be looking at. If you're talking about clicking on those 6 images, then the problem is probably due to that fact that the layout is changing, i.e. the images are changing in size, so the top of where they appear in the document is not constant. That's something you'll need to make adjustments for when creating your scroll tween. 1 Link to comment Share on other sites More sharing options...
Author Share Posted May 13, 2022 Hello, sorry if my explanations were not clear but yes, it is related to these images. I have just done a test by deactivating the change of the image size and it works correctly. So you are right, I have to find a way to take into account the changing size of the element to resolve my issue. I will try to find a solution, Thank you for your help 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