omi Posted August 11, 2023 Share Posted August 11, 2023 i trying to create card stacking animation on scroll similar to https://swagapp.com/?ref=godly website. Query: How i can set start and End values dynamically according to the browser because I'm checking on normal desktop (1366 * 768) is working but when i checking on the large device large white space is showing. how i can the card position always middle of the screen you can check the reference website but i want exactly https://swagapp.com/?ref=godly See the Pen jOQjyQG by omi-bhatia (@omi-bhatia) on CodePen Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 Hi @omi there are multiple ways You can use function based values, here I just get the current window height and do that times 3 // What you have right now start: "50% 50%", // when the top of the trigger hits the top of the viewport end: "100% 40%", // end after scrolling 500px beyond the start // Function based values based on screen size start: "50% 50%", end: () => `${window.innerHeight * 3} 40%`, Also check out gsap.matchMedia() with which you can do css type media queries based on screen size https://greensock.com/docs/v3/GSAP/gsap.matchMedia() Also it is better to animate more performant type properties eg instead of top, try animating y or yPercent After digging some deeper in your code, I have a few more points, check out this video GSAP becomes a lot easier if you leave GSAP for what it is and first focus on CSS. Personally I lay out everything with CSS where I want elements to end up, then I just can do a simple .from() tween to get them where I want them to start from. I've moved a lot of your CSS around and removed the top: 400% offsets, these really over complicate things. I've used a simple CSS Grid on the parent and set all .cards to lay on top of each other, and I then of set them based on their nth-child position. (same as the video above) It all then looks like this See the Pen VwVJpdP?editors=0100 by mvaneijgen (@mvaneijgen) on CodePen When my CSS is 100% correct I focus on the animation See the Pen OJaepwQ?editors=0100 by mvaneijgen (@mvaneijgen) on CodePen See there is no ScrollTrigger, that is because the best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. See the Pen zYMVZJx?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen Hope it helps and happy tweening! 2 Link to comment Share on other sites More sharing options...
omi Posted August 11, 2023 Author Share Posted August 11, 2023 31 minutes ago, mvaneijgen said: Hi @omi there are multiple ways You can use function based values, here I just get the current window height and do that times 3 // What you have right now start: "50% 50%", // when the top of the trigger hits the top of the viewport end: "100% 40%", // end after scrolling 500px beyond the start // Function based values based on screen size start: "50% 50%", end: () => `${window.innerHeight * 3} 40%`, Also check out gsap.matchMedia() with which you can do css type media queries based on screen size https://greensock.com/docs/v3/GSAP/gsap.matchMedia() Also it is better to animate more performant type properties eg instead of top, try animating y or yPercent After digging some deeper in your code, I have a few more points, check out this video GSAP becomes a lot easier if you leave GSAP for what it is and first focus on CSS. Personally I lay out everything with CSS where I want elements to end up, then I just can do a simple .from() tween to get them where I want them to start from. I've moved a lot of your CSS around and removed the top: 400% offsets, these really over complicate things. I've used a simple CSS Grid on the parent and set all .cards to lay on top of each other, and I then of set them based on their nth-child position. (same as the video above) It all then looks like this When my CSS is 100% correct I focus on the animation See there is no ScrollTrigger, that is because the best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. Hope it helps and happy tweening! Comment: we want to hide all cards except the first card . did you check the reference website ? Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 4 minutes ago, omi said: Comment: we want to hide all cards except the first card . did you check the reference website ? I don't know what you mean. To me it looks exactly like the reference website, the offset might be a bit off, but that you can fix with CSS. Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 Do you mean that the cards should come from off screen? Then just change where the card should come from. My previous demo transformed them in the Y direction 100% of the height of the card, but below example animates them from a Y of the height of the current window. See the Pen dyQBWOZ?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen Link to comment Share on other sites More sharing options...
omi Posted August 11, 2023 Author Share Posted August 11, 2023 1 hour ago, mvaneijgen said: I don't know what you mean. To me it looks exactly like the reference website, the offset might be a bit off, but that you can fix with CSS. Thanks for quick response. sorry for my bad English Please check this link https://prnt.sc/Y6S0lja0p0dc on viewport one card are showing at one time but when user scroll then next card will show how i can achieve this ? i hope this helps you to understand but i want to implement i had implemented the same but only issue the placement of cards is not middle of the screen on every resolution i also checked your codepen you have made same changes in css and animation but still same issue all cards are showing on viewport default without scrolling https://prnt.sc/UTtMkcisykS5 Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 Codepen might be weird with window.innerHeight if you fork my latest version and open the debug menu you will see it works as expected. See the Pen dyQBWOZ by mvaneijgen (@mvaneijgen) on CodePen Link to comment Share on other sites More sharing options...
omi Posted August 11, 2023 Author Share Posted August 11, 2023 19 minutes ago, mvaneijgen said: Codepen might be weird with window.innerHeight if you fork my latest version and open the debug menu you will see it works as expected. Thanks for quick response and helping i have download the codepen any open in browser on large device working fine by on normal resolution (1366 * 768) last card fully visible tl.from(".panel__card--two", { y: () => window.innerHeight}); can you please explain this logic Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 1 hour ago, omi said: normal resolution (1366 * 768) last card fully visible Please remove everything to do with GSAP and check if the issue still persist. I think is probably will. There is no amount of JavaScript that will fix a CSS layout, so it is really import to fix the css before adding any GSAP code. 1 hour ago, omi said: tl.from(".panel__card--two", { y: () => window.innerHeight}); can you please explain this logic Instead of using a fixed pixel value or a percentage based value you can also do something dynamic. Eg here I get the height of the current window. This way it is always just off screen. No matter if the screen is 600px high or 3000px 1 Link to comment Share on other sites More sharing options...
omi Posted August 11, 2023 Author Share Posted August 11, 2023 32 minutes ago, mvaneijgen said: Please remove everything to do with GSAP and check if the issue still persist. I think is probably will. There is no amount of JavaScript that will fix a CSS layout, so it is really import to fix the css before adding any GSAP code. Instead of using a fixed pixel value or a percentage based value you can also do something dynamic. Eg here I get the height of the current window. This way it is always just off screen. No matter if the screen is 600px high or 3000px .panel__stack { --spacer:4rem; min-height: 120vh; position: relative; display: grid; grid-template-columns: 1fr; grid-template-rows: 1fr; grid-column-gap: 0px; grid-row-gap: 0px; align-items: center; justify-items: center; } min-height is conflicting with the layout if i'm changing the dimension they will work differently on all devices can you suggest me how to add the spacing below the last card Link to comment Share on other sites More sharing options...
mvaneijgen Posted August 11, 2023 Share Posted August 11, 2023 CSS, CSS, CSS. It is the most important step when designing a layout for animation. The issue its, that if you put bad CSS in you get bad animations at the other end. I can't fix your layout for you, that is something you have to get better at, keep in mind less is more in this case I've tried some hacks, to calculate the height of the cards with all there offsets, but I don't know how this will hold up in the real world. Hope it helps and happy tweening! See the Pen xxQoPjQ?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen 2 Link to comment Share on other sites More sharing options...
Solution omi Posted August 12, 2023 Author Solution Share Posted August 12, 2023 16 hours ago, mvaneijgen said: CSS, CSS, CSS. It is the most important step when designing a layout for animation. The issue its, that if you put bad CSS in you get bad animations at the other end. I can't fix your layout for you, that is something you have to get better at, keep in mind less is more in this case I've tried some hacks, to calculate the height of the cards with all there offsets, but I don't know how this will hold up in the real world. Hope it helps and happy tweening! it seems it's working ver very thanks Link to comment Share on other sites More sharing options...
Toso Posted August 13, 2023 Share Posted August 13, 2023 @omi I have created this section, the tricky part was making the buttons work along with the animation itself, I used scrolltoplugin to solve this problem but it create another bug on refresh let me know if you made it work and how you did it Link to comment Share on other sites More sharing options...
omi Posted August 14, 2023 Author Share Posted August 14, 2023 7 hours ago, Toso said: @omi I have created this section, the tricky part was making the buttons work along with the animation itself, I used scrolltoplugin to solve this problem but it create another bug on refresh let me know if you made it work and how you did it @Toso can you share your code because tabs highlight on scrolling is pending 1 Link to comment Share on other sites More sharing options...
Toso Posted August 14, 2023 Share Posted August 14, 2023 const boxes = gsap.utils.toArray(".epitems__singleItem"); const scrollNav= gsap.utils.toArray(".scroll-btn"); let index = 0; const endTime = 1000 * boxes.length; gsap.set(".epitems__singleItem", { position: "absolute", transformOrigin: "top" }); gsap.set(".epitems__singleItem:not(:first-child)", { yPercent: 140 }); function activeDot() { gsap.to(scrollNav, { border: "1px solid transparent", ease: "sine", duration: 0.1 }); gsap.to(scrollNav[index], { border: "1px solid #391952", ease: "sine", duration: 0.5 }); } let boxTL = gsap.timeline({ scrollTrigger: { trigger: main.current, start: "top top", end: `'+=${endTime}px'`, scrub: 2, pin: true, }, }); //************************************* option 1 for animation boxes.forEach((e, i) => { gsap.set(e, { marginTop: () => i * 15 }); boxTL.to(e, { keyframes: [{ yPercent: 0 }, { scale: () => 0.85 + i * 0.03 }], onUpdate: () => { index = i; activeDot(); } }); }); //************************* thats the first part make sure its working with you so we can move to the next part and stuff dont get complicated , for the animation when you use onUpdate callback it will solve the problem that you have with tab highlighting also the animation here is one of 2 options i tried but thats the simple one , the other one i used a nested loop inside onComplete & onReverseComplete callbacks to get the the same result like the ref section from swag Link to comment Share on other sites More sharing options...
Toso Posted August 14, 2023 Share Posted August 14, 2023 boxes.forEach((e, i) => { gsap.set(e, { marginTop: () => i * 15 }); boxTL.to(e, { yPercent: 0 , onUpdate: () => { index = i; activeDot(); }, onComplete: () => { e.classList.add("active-box"); gsap.utils.toArray(".active-box").forEach((x) => { let currentScale = gsap.getProperty(x, "scale"); gsap.to(x, { scale: () => currentScale - 0.025, }); }); }, onReverseComplete: () => { e.classList.remove("active-box"); gsap.utils.toArray(".active-box").forEach((x) => { let currentScale = gsap.getProperty(x, "scale"); gsap.to(x, { scale: () => currentScale + 0.025, }); }); }, }); }); //******************** thats the second option if you want to get the same animation and everything but im still trying to make it better Link to comment Share on other sites More sharing options...
omi Posted August 14, 2023 Author Share Posted August 14, 2023 1 hour ago, Toso said: const boxes = gsap.utils.toArray(".epitems__singleItem"); const scrollNav= gsap.utils.toArray(".scroll-btn"); let index = 0; const endTime = 1000 * boxes.length; gsap.set(".epitems__singleItem", { position: "absolute", transformOrigin: "top" }); gsap.set(".epitems__singleItem:not(:first-child)", { yPercent: 140 }); function activeDot() { gsap.to(scrollNav, { border: "1px solid transparent", ease: "sine", duration: 0.1 }); gsap.to(scrollNav[index], { border: "1px solid #391952", ease: "sine", duration: 0.5 }); } let boxTL = gsap.timeline({ scrollTrigger: { trigger: main.current, start: "top top", end: `'+=${endTime}px'`, scrub: 2, pin: true, }, }); //************************************* option 1 for animation boxes.forEach((e, i) => { gsap.set(e, { marginTop: () => i * 15 }); boxTL.to(e, { keyframes: [{ yPercent: 0 }, { scale: () => 0.85 + i * 0.03 }], onUpdate: () => { index = i; activeDot(); } }); }); //************************* thats the first part make sure its working with you so we can move to the next part and stuff dont get complicated , for the animation when you use onUpdate callback it will solve the problem that you have with tab highlighting also the animation here is one of 2 options i tried but thats the simple one , the other one i used a nested loop inside onComplete & onReverseComplete callbacks to get the the same result like the ref section from swag @Toso Thanks for sharing the code do you have demo link to check the output? Link to comment Share on other sites More sharing options...
omi Posted August 14, 2023 Author Share Posted August 14, 2023 3 hours ago, Toso said: boxes.forEach((e, i) => { gsap.set(e, { marginTop: () => i * 15 }); boxTL.to(e, { yPercent: 0 , onUpdate: () => { index = i; activeDot(); }, onComplete: () => { e.classList.add("active-box"); gsap.utils.toArray(".active-box").forEach((x) => { let currentScale = gsap.getProperty(x, "scale"); gsap.to(x, { scale: () => currentScale - 0.025, }); }); }, onReverseComplete: () => { e.classList.remove("active-box"); gsap.utils.toArray(".active-box").forEach((x) => { let currentScale = gsap.getProperty(x, "scale"); gsap.to(x, { scale: () => currentScale + 0.025, }); }); }, }); }); //******************** thats the second option if you want to get the same animation and everything but im still trying to make it better Can you provide the demo link with compelete htm, css and javascript Link to comment Share on other sites More sharing options...
Toso Posted August 14, 2023 Share Posted August 14, 2023 I don't have an online demo for this section only iam sorry I created it inside a project currently working on it, it's a nextjs app Link to comment Share on other sites More sharing options...
Toso Posted August 14, 2023 Share Posted August 14, 2023 that the html and css , nothing fancy here just 4 boxes with all the styling from the ref same thing for nav ,, and everything after that was created in js Link to comment Share on other sites More sharing options...
omi Posted August 17, 2023 Author Share Posted August 17, 2023 On 8/11/2023 at 8:41 PM, mvaneijgen said: CSS, CSS, CSS. It is the most important step when designing a layout for animation. The issue its, that if you put bad CSS in you get bad animations at the other end. I can't fix your layout for you, that is something you have to get better at, keep in mind less is more in this case I've tried some hacks, to calculate the height of the cards with all there offsets, but I don't know how this will hold up in the real world. Hope it helps and happy tweening! is it possible to hightlight the navabar according to the section? Link to comment Share on other sites More sharing options...
omi Posted August 25, 2023 Author Share Posted August 25, 2023 On 8/11/2023 at 8:41 PM, mvaneijgen said: CSS, CSS, CSS. It is the most important step when designing a layout for animation. The issue its, that if you put bad CSS in you get bad animations at the other end. I can't fix your layout for you, that is something you have to get better at, keep in mind less is more in this case I've tried some hacks, to calculate the height of the cards with all there offsets, but I don't know how this will hold up in the real world. Hope it helps and happy tweening! How to manage the card because on some laptops complete content is not visible is it possible to keep the white space always at bottom of the card at moment card is touching at the bottom of window Link to comment Share on other sites More sharing options...
GSAP Helper Posted August 25, 2023 Share Posted August 25, 2023 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 Stackblitz that demonstrates the issue? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. 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 starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen Using a framework/library like React, Vue, Next, etc.? CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: React (please read this article!) Next Svelte Sveltekit Vue Nuxt Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 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...
omi Posted August 25, 2023 Author Share Posted August 25, 2023 (edited) Thanks for the Gsap community to help me on this task minimal demo : See the Pen yLGYvqp by omi-bhatia (@omi-bhatia) on CodePen I tired to make the same animation effect like "swagapp" website but i am facing some issue like 1. on pinned the card content is cutting and card is touching at bottom of the window . how i can set the white space at below card? 2. how i can set the delay between timelines for now slide moves very fast. 3. how to make a click functionality so that user can direct go to particular slide means card can move on scroll and on click. Similar animation like swagapp.com website Edited August 25, 2023 by omi forget to add the codepen link Link to comment Share on other sites More sharing options...
Rodrigo Posted August 25, 2023 Share Posted August 25, 2023 Hi, I don't really understand what you mean with this: 2 hours ago, omi said: 1. on pinned the card content is cutting and card is touching at bottom of the window . how i can set the white space at below card? @mvaneijgen already linked a video where @Cassie talks about this: 2 hours ago, omi said: 2. how i can set the delay between timelines for now slide moves very fast. 2 hours ago, omi said: 3. how to make a click functionality so that user can direct go to particular slide means card can move on scroll and on click. Check this example: See the Pen bGmrrEX by GreenSock (@GreenSock) on CodePen Hopefully this helps. Happy Tweening! 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