Jump to content
Search Community

GreenSock last won the day on April 21

GreenSock had the most liked content!

GreenSock

Administrators
  • Posts

    23,135
  • Joined

  • Last visited

  • Days Won

    817

Everything posted by GreenSock

  1. Yeah, I would never expect CSS and JS animations to remain synchronized. They use completely different timing mechanisms and threads. GSAP has lag smoothing too, but CSS wouldn't match that. In short, if you're trying to build something such that CSS and JS animations are 100% perfectly synchronized, I'd give up immediately and adjust your strategy. Obviously I'd recommend just using GSAP because you'll get way more flexibility overall and everything will remain synchronized.
  2. One other thing you could try on mobile is ScrollTrigger.normalizeScroll(true) to force the scrolling to happen on the main thread. Does that help at all? You could also use ScrollSmoother with a very small smoothTouch value. (That requires a Club GSAP membership though)
  3. That seems a little more verbose than necessary: // LONG width: () => gsap.utils.random(0, 20, true)() + "%" // SHORTER width: () => gsap.utils.random(0, 20) + "%"
  4. I'm not able to replicate the issue, but I noticed a few things: This doesn't make sense: start: "bottom top", end: "bottom bottom", The bottom of the element would hit the bottom of the viewport BEFORE it hits the top, thus you're setting it up so that your start is AFTER your end (inverted). You're creating your timeline OUTSIDE of your matchMedia(), and adding a tween inside. That's generally a bad idea - don't you want it to clean up the whole timeline if that matchMedia() reverts? I mean what's the point of you creating an empty timeline when that matchMedia() doesn't match anyway? Instead of animating to width: auto (which isn't even numeric, making it difficult to interpolate), why not make it a function-based value that you calculate a pixel value on? Or better yet, since it just conforms to the child <svg> which you explicitly set to 137px, why not animate to that specific value? I would not recommend animating the generic "margin" value because that is composed of several values. Instead, animate the individual parts that you want. // BAD margin: "50px 0 0 0" // GOOD marginTop: "50px" I hope that helps.
  5. No, those values were just taken from the tool that @Rodrigo pointed you to previously. I have no idea where Matthew got those numbers. They're likely an approximation. Your goal is to create a GSAP animation that eases in EXACTLY the same way as a CSS animation? Why? That seems very strange to me. If your goal is to have them perfectly synchronized, I don't think that's even possible to do because of the way browsers work. Why would you not just use GSAP? It gives you much, much more power and flexibility that CSS. 🤷‍♂️
  6. Example: CustomEase.create("in-out", "0.42,0,0.58,1") And then: gsap.to(".box", { ease: "in-out", ... });
  7. I noticed two problems: You nested ScrollTriggers inside a timeline. That's logically impossible to accommodate - the playhead of a tween can't be controlled by BOTH a timeline's playhead AND the scroll position simultaneously. You've got multiple tweens of the same element controlled by ScrollTriggers. By default, animations with ScrollTriggers are rendered immediately. So in your case, you just need to set the 2nd and 3rd to immediateRender: false so that they don't step on each other. Is this what you're looking for?: https://codepen.io/GreenSock/pen/QWPzBXO?editors=1010 And alternative might be to create a timeline that has ONE ScrollTrigger applied to the timeline itself (not nested ones), and have all your animations in there. That'd assume you can just make that one timeline span across the entire scroll area that you need. If not, then just stick with the individual tweens. I hope that helps.
  8. Like @Rodrigo, I don't understand what you're seeing - I can see those countdown sections on both my Mac and my iPhone. Maybe I'm missing something obvious. 🤷‍♂️
  9. Yeah, if you check the console there's a warning: It's just not something that can be accommodated at this point - you've got your SVG set up to scale in a non-uniform way. Sorry, I wish there was a magic bullet I could offer.
  10. Maybe try making sure you've got the latest version of the files? I'm totally guessing here. Very tough to say without a minimal demo, sorry.
  11. I'm not familiar with Nuxt, but why are you doing this?: const { $gsap } = useNuxtApp() That's what's throwing the error - it's not returning $gsap. Why aren't you just doing a normal gsap import? Like: import gsap from "gsap";
  12. I noticed several problems: You had faulty markup (missing closed </div> tags) You were defining a containerAnimation for the getScrollLookup(), but only some of the elements were in the containerAnimation. That is not valid. You were pinning a container element, but you didn't define that in the getScrollLookup() config. Is this more of what you wanted? https://codepen.io/GreenSock/pen/RwOEWYW?editors=0010
  13. I believe that's the issue that was already reported and patched in this thread related to once: true: The patch hasn't been released yet, but it's very easy to work around by just creating a simple ScrollTrigger first (it doesn't need to do anything). https://stackblitz.com/edit/stackblitz-starters-vynow2?file=src%2Fcomponents%2FHeroIntro%2FHeroIntro.js Does that clear things up?
  14. This appears to be funky behavior caused by Vue forcing refs to be Proxy objects. So when you access ref.value, it isn't the real object at all! It's a Proxy which alters what "this" refers to inside method calls. I think it's terrible that Vue does this actually, but maybe they have good reason for it. 🤷‍♂️ From what I can tell, the solution would be to use a shallowRef() instead of ref(): https://stackblitz.com/edit/github-vfgcdf-g52l6b?file=app.vue Does that clear things up?
  15. Without a minimal demo, it's super difficult to offer a suggestion here or understand what you're asking for - are you saying you want to apply ScrollSmoother...but not have it actually work at all? You just want to have it pretend to work, feeding you the value that it would apply to the container's transform, without applying it? Maybe you could add a ticker listener with a high priority to grab the original transform, and then use an onUpdate on the ScrollSmoother where you grab the new value but immediately apply the old one to revert it(?) I'm totally guessing here in the absence of a minimal demo, but hopefully that gives you a little to go on at least. I wonder why you wouldn't adjust whatever you're doing with the <body> transform to more cleanly apply that in a way that integrates with ScrollSmoother(?)
  16. Does it work well for you without Lenis? That's not a GreenSock product, so we can't really support it here. If you're talking about the pin seeming to be a little bit tardy, that's likely because mobile browsers are particularly bad with using a separate, non-synchronized thread for scrolling which is why ScrollTrigger offers a anticipatePin option. You might want to try adding anticipatePin: 1 or some other value just to see if it helps. You could also see if it's any better with ScrollTrigger.normalizeScroll(true);
  17. That's because your path data isn't valid. You specified type: "cubic" but your path data only has 3 points instead of 4.
  18. I assume maybe you mean something like this?: let tween1, tween2; function invalidateAndRemakeAnimations() { // Kill existing animations tween1 && tween1.revert(); tween2 && tween2.revert(); // Remake the first animation tween1 = gsap.to(".row._1", { scrollTrigger: { trigger: ".row._1", start: "top top", scrub: true, pin: true, pinSpacing: false, invalidateOnRefresh: true, markers: true } }); // Remake the second animation tween2 = gsap.to("h2.text", { scrollTrigger: { trigger: ".row._3", start: "top top", scrub: true, invalidateOnRefresh: true }, position: "relative" }); }
  19. Thanks for asking, @Marija1337! No, you don't need the special commercial license for that - the standard "no charge" license covers that type of usage. If you answer "yes" to any of the following, you'd need the special commercial license that comes with "Business" Club GSAP memberships: Do you have multiple developers that need access to the bonus plugins like SplitText, ScrollSmoother, MorphSVG, etc.? Does your GSAP-enhanced website/game/product require the user to pay a fee to use? (like Netflix.com) Are you selling a GSAP-enhanced product to multiple end users? (like a website template, theme or game) Are you using GSAP in a game/app with optional paid features/upgrades? If your website sells products that aren't GSAP-enhanced like clothing, widgets, food, etc., that doesn't require the commercial license. It only matters if the thing for which a fee is collected uses GSAP in some way. The standard "no charge" license even covers usage in projects where only a one-time development fee is charged, like an agency that's paid to build a fancy web site that's free for everyone to use. So you should be all set with the free/public license. Enjoy the tools and good luck with the new business! 💚
  20. Again, it's tough to advise without seeing a minimal demo, but I guess the most generic answer I can give would be: "call kill() on that animation from inside a 'resize' event handler". But if you want a more targeted answer for your scenario, please provide a minimal demo that clearly illustrates the problem and we'd be happy to take a peek.
  21. Or you could just put the CustomEase inside your onMounted function. The fundamental problem is that you're trying to register CustomEase when window/document don't exist yet.
  22. Yeah, it's almost impossible to troubleshoot without a minimal demo, but I bet this has nothing to do with GSAP. Keep in mind that Safari handles stacking order on 3D elements differently than all other browsers. It's as if they combine z-index and z placement on the 3D axis. My suggestion would be to eliminate GSAP from the equation and just set the values directly (no animation) and see if it displays the way you'd expect. You may need to move things on the z-axis in order to get them to stack properly. If you still need help, please post a minimal demo.
  23. Another option: just use a super small data-speed: https://codepen.io/GreenSock/pen/rNbqwMQ?editors=1010
  24. @Chromium One of the MOST important things to us at GreenSock is cultivating a warm, smart, non-shaming community. We're widely known as having forums that are uncommonly so. Most tech communities are characterized by harsh, arrogant, shaming responses. When someone has a question, it takes a lot of humility and courage to risk posting. We get it. We really try to be compassionate and gentle. It sounds like you felt criticized and insulted. I'm very sorry if that was your experience. We actively work to avoid that; if we failed, I hope you'll forgive us. Glad we ultimately got on the same page with a solution. 🥳
  25. Yes, @Rodrigo is correct about that not being a built-in feature but you could probably get that functionality with enough custom code. For example, set up a listener for the "scrollEnd" event, and then create a gsap.to(...{ scrollTo }) tween that's however long you want, and apply your snapping logic inside the handler to calculate the scroll position. Just an idea. Good luck!
×
×
  • Create New...