Jump to content
GreenSock

Leaderboard

Popular Content

Showing content with the highest reputation on 02/01/2023 in all areas

  1. @GreenSock: Thank you so very much, Jack! I somehow feel bad that you did this while you are ill, but I won't question your decision. The new version works exactly as intended. Thank you for the explanation, I wasn't surprised to see the onRefresh() after the creation of a ScrollTrigger instance—I would have been if I hadn't seen it, I guess. My musings were meant to help those overwhelmed by all those logs, but it seems they did not. It is, and I was aware that I'wasn't doing a very good job with it. I did start out with a real minimal demo at first, but after several tries and 2 plus hours of trying I couldn't reproduce the issue. As I had the previously working very complex example, I finally went on reducing 1200 Lines of code to 400, where I hoped that It would be easy to ignore half of it. I will try to do better next time. Again thank you and @Cassie and @Rodrigo too for being very helpful and patient as always! I wish you fast and full recovery, Jack and send you a big package of thankful thoughts.
    4 points
  2. I spent a few hours digging into this with my foggy COVID-brain and I think I found the very rare edge case related to snapping and the fact that when you apply a ScrollTrigger to a timeline it has to wait for a tick before it actually refreshes that instance (otherwise the timeline would likely be empty...people create timelines and THEN populate them so we can't do the refresh() right away). Here's a beta file: https://assets.codepen.io/16327/ScrollTrigger.min.js (you probably need to clear your cache) Better? Also, I wanted to make sure you understood that when you did your ScrollTrigger.config({ autoRefreshEvents: "..."}) stuff, that only affects when a full ScrollTrigger.refresh() gets called automatically (for ALL ScrollTriggers). But each individual ScrollTrigger has to refresh() initially when created, otherwise they wouldn't have any start/end values It looked like you were surprised to see the onRefresh() callback triggered when you were re-creating your ScrollTrigger(s) on resize, but that's totally normal. Let me know if you need more clarity around that. Does the beta file behave the way you'd expect? It was quite a challenge to try to follow the 400+ lines of your TypeScript demo in my condition 🙃 In the future, I'd definitely recommend trying to strip things back further. Like if the problem is that resizing results in the scroll jumping to the very end, maybe try to do the most basic demo possible and if it works, start layering things on (like in this case, you'd need snapping). Then the moment it breaks, you know exactly what it was and we can avoid all that extra complexity. I know you were trying to be helpful with all those logs/traces. It was a bit of information overload, and there were so many pieces all firing at various times which I think just made it more convoluted than it needed to be. I do appreciate the intent. Hopefully the beta resolves things for you though and you don't need to mess with the demo anymore. Thanks for putting the effort into creating the demo! I know it's always a challenge. Creating a minimal demo is quite an art form, I know.
    4 points
  3. Animation code can get lengthy, but GSAP exists to make sure it isn't unwieldy. It's hard to advise without understanding your use case - you can avoid duplicating code by looping around sections, if that suits your animations. But if each section is different, there's nothing wrong with creating a timeline per section with 20+ tweens on
    3 points
  4. Have you tried using useLayoutEffect instead of isomorphic?
    2 points
  5. This is definitely more advanced, but you can certainly do it. You'll want to check out: https://greensock.com/docs/v3/Plugins/Draggable https://greensock.com/docs/v3/Plugins/MorphSVGPlugin
    2 points
  6. 2 points
  7. Hi, Can you test the next release of ScrollTrigger and let us know how it works: https://assets.codepen.io/16327/ScrollTrigger.min.js Happy Tweening!
    2 points
  8. Hi @Alan Brown and welcome to the GreenSock forums! First thanks for being a Club GreenSock member and supporting GreenSock! I removed the link for your example since you pushed your .npmrc file with your private npm token in it. Please remove that and instead use the gsap-trial package in Codesandbox and Stackblitz. When you updated the example add another post in this thread with the new URL. This is happening only in the intro.tsx file or in every component you have? Where exactly are you creating your ScrollSmoother instance? I couldn't find that anywhere in your code. Can you please narrow this down to the component(s) that are actually giving you problems? Is really hard to fish issues in such a large app and we don't have the time resources to comb through a large code base like yours. If possible isolate the section(s) where this is happening and create a codepen example just for that. It would be good to isolate just the methods you're using for creating the text animations. You can use this Codepen template: https://codepen.io/GreenSock/pen/aYYOdN The only thing I can tell you right now is that you should create your ScrollSmoother instance first and then create the ScrollTrigger instances. Is also worth noticing that React render child components first and then the parent. Since is most likely that a parent is holding the ScrollSmoother instance you should be able to communicate to the child elements that the ScrollSmoother instance is ready. If you prefer you can use this starter template for using Next with ScrollSmoother and just add the component and methods that are giving you problems: https://stackblitz.com/edit/nextjs-efumgr Happy Tweening!
    2 points
  9. Hi @SpaceHorse welcome to the forum! Mix and matching ScrollTriggers is not something that is really possible, what you could do in this scenario is update the timeline that is already being played and add your new tweens to that timeline. The only issue is that this timeline is not being scrubbed and will just play the animation. https://codepen.io/mvaneijgen/pen/qByQqJd?editors=0010 This particular demo is for this exact effect nothing more and nothing less, if you thus want to have different animations per section you'll be better off starting from scratch instead of modifying this demo. Personally what I would do is removing ScrollTrigger! 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. I would thus start by writing the animations on a timeline, here is some pseudo code. tl.to(blue, { animate out}) tl.to(red, { animate in}) tl.to(red hello text, { spin around }) tl.to(red, { animate out }) tl.to(orange, { animate in }) ... ect Then when you're happy with the animation, add ScrollTrigger to it. Bellow is a great example video, but the only thing is here it is one tween with a ScrollTrigger and I would suggest for you to create a timeline with the ScrollTrigger on that timeline. Hope it helps and happy tweening! Edit: couldn't help my self. Here is a basic setup on how I would go about it. https://codepen.io/mvaneijgen/pen/bGjQgWQ?editors=0010
    2 points
  10. Hi, I have the same issue with my webpack 5 configuration, I'm using. gsap 3.11.4 and I don't have any problem in development mode but when I build my project, I have the same error. I added the line below and it's working now, I did not have this problem in other projets. gsap.core.globals("ScrollTrigger", ScrollTrigger); I already used this webpack configuration and I don't have any problem before. Does anyone have an idea what is the problem and how to fix it ? Thanks EDIT: Its seems that the problem came from TerserPlugin
    2 points
  11. This is not documented (and is considered experimental), but if you want to force ScrollSmoother to use whole pixel values, just add this to the config: wholePixels: true https://codepen.io/GreenSock/pen/MWBPZVE
    2 points
  12. Hi, As I mentioned before this seems more related to when the ScrollTrigger instances are created more than anything else. As soon as I wrapped the method you're using to create the animations inside a timeout it works: https://stackblitz.com/edit/nextjs-fkstzp?file=pages%2F_app.js,pages%2Findex.js,components%2FIntro.js,components%2FOverview.js What you need is a way to communicate to the child components that the ScrollSmoother instance is created. Another option could be, seeing that you have everything in just one page, to conditionally render the components after the ScrollSmoother instance is done. Happy Tweening!
    1 point
  13. To achieve this, you'll want to get the position of each circle and check that against the position of your cursor (or use a mouseEnter or mouseOver event listener), I think it'd be best to use something like quickTo to change position of the follow ring. Docs on quickTo here: https://greensock.com/docs/v3/GSAP/gsap.quickTo()
    1 point
  14. This is just a little helper function I'm afraid, no docs. I've added in an option to loop for you. It'll be repeat though, not loop, because we're in scrollTrigger land, not Lottie land. https://codepen.io/GreenSock/pen/LYBXejB Here's some notes function LottieScrollTrigger(vars) { // this is grabbing all the stuff you pass through let playhead = { frame: 0 }, target = gsap.utils.toArray(vars.target)[0], speeds = { slow: "+=2000", medium: "+=1000", fast: "+=500" }, duration = vars.duration || 0.5, // I've added these for you repeat = vars.repeat || false, // I've added these for you // this is the scrollTrigger vars object st = { trigger: target, pin: true, start: "top top", end: speeds[vars.speed] || "+=1000", scrub: 1 }, ctx = gsap.context && gsap.context(), // this is Lottie doing it's thing animation = lottie.loadAnimation({ container: target, renderer: vars.renderer || "svg", loop: false, autoplay: false, path: vars.path, rendererSettings: vars.rendererSettings || { preserveAspectRatio: "xMidYMid slice" } }); for (let p in vars) { // let users override the ScrollTrigger defaults st[p] = vars[p]; } // wait until the DOM is loaded animation.addEventListener("DOMLoaded", function () { // and make a tween to play the lottie animation using everything we passed through let createTween = function () { animation.frameTween = gsap.to(playhead, { frame: animation.totalFrames - 1, ease: "none", duration: duration, // they get used here repeat: repeat, // here you go! onUpdate: () => animation.goToAndStop(playhead.frame, true), scrollTrigger: st // this is the scrollTrigger stuff }); return () => animation.destroy && animation.destroy(); }; // don't worry about this ctx && ctx.add ? ctx.add(createTween) : createTween(); // in case there are any other ScrollTriggers on the page and the loading of this Lottie asset caused layout changes ScrollTrigger.sort(); ScrollTrigger.refresh(); }); return animation; }
    1 point
  15. Ok, so we've used Smoother on our site, which is built on Next.js. We setup our Smoother in _app.js (not sure this matters) This is what that code looks like: const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; useIsomorphicLayoutEffect(() => { if (!ScrollTrigger.isTouch) { scroller.current = ScrollSmoother.create({ normalizeScroll: true, smooth: 2, }); } else { ScrollTrigger.config({ ignoreMobileResize: true }); } }, []); Everywhere else we are using regular useEffects(() => {}, []), just making sure to check if the element/ref is available.
    1 point
  16. Hey Cassie - yes that helps a ton! I am having a little trouble understanding all of what's going on here (mostly in the LottieScrollTrigger function), but I think I can work with it. Are there docs that explain it, or this a custom function? Mainly, I would like my ".animation" lotties to loop while in the viewport. I tried adding some parameters (loop: true/false) to the scrolltrigger like you did with the duration, but that didn't work. I've updated my Codepen so you can see what I was trying to do there. Is there a way to do that as well? Either way this was extremely helpful. Thank you so much!!
    1 point
  17. You may need to run a ScrollTrigger.refresh() when the page loads up... My guess is that in production ScrollTrigger is setting up before all the dom content is setup.
    1 point
  18. Hey @cassie For my project I need this Scrolltrigger to do some animations and stuffs, but in my Codepen example I simplified the code so it just adds markers I need the markers to be placed at the top and the bottom of the black container. Right now they're floating in the page but not following the black container, because the black container stops scrolling for a moment when its parent get pinned, so the calculation of the top and the bottom are "wrong" I hope this is more clear
    1 point
  19. Just an FYI, we created a version in Vue3 as well, in case anyone is interested in that: https://stackblitz.com/edit/vitejs-vite-tn1wsx Happy Tweening!
    1 point
  20. Sick! That worked and solves another issue I saw. Thanks for your time.
    1 point
  21. That looks like you've written out console.log("GSAP", "ScrollTrigger") with strings I don't think you've got your scripts enqueued properly though. I would expect to see the GSAP object returned. Could you copy paste this snippet in for me? console.log(gsap, "💚") This should be what you get back And this is the correct way to enqueue your scripts. // The proper way to enqueue GSAP script in WordPress // wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); function theme_gsap_script(){ // The core GSAP library wp_enqueue_script( 'gsap-js', 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js', array(), false, true ); // ScrollTrigger - with gsap.js passed as a dependency wp_enqueue_script( 'gsap-st', 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/ScrollTrigger.min.js', array('gsap-js'), false, true ); // Your animation code file - with gsap.js passed as a dependency wp_enqueue_script( 'gsap-js2', get_template_directory_uri() . 'js/app.js', array('gsap-js'), false, true ); } add_action( 'wp_enqueue_scripts', 'theme_gsap_script' ); We can try to help but we're not wordpress experts here. Maybe give this wordpress support discord a go if we can't help? https://disboard.org/server/991553521197518878
    1 point
  22. Sure, you can add start and end markers wherever you need. It'll just have to be a little more custom! https://codepen.io/GreenSock/pen/JjBeWPO?editors=0010
    1 point
  23. Yep, that would work! https://codepen.io/GreenSock/pen/PoBxWYE?editors=0111
    1 point
  24. 1 point
  25. Don't cry! We'll sort it out. If you log out console.log(gsap, ScrollTrigger) - what do you get in return?
    1 point
  26. I made this workaround, const subTween = gsap.to(".text", { opacity: 1, paused: true, }); const mainTimeline = gsap .timeline() .to(".class", { opacity: 0, }) .to(".something", { yPercent: 200, onComplete: () => { subTween.play(); }, }); onComplete function will only be fired when the timeline on play not on reverse. You can control the time of the sub tween using the delay property.
    1 point
  27. I haven't tried other libraries for smooth scrolling. I'm a Gsap fan In the latest version of Google Chrome, scrolling is smooth by default on all sites and there is no such issue. This plugin is more than just smooth scrolling. These are very convenient and beautiful functions (speed, lag, paused ) I have no idea how to fix this because I don't even understand why this is happening. There is no pattern in colors. Close shades have different behavior
    1 point
  28. Hi, Here is the example: https://stackblitz.com/edit/vitejs-vite-w9jxwd I'm using everything inside the useLayoutEffect and the GSAP Context instance to add a method for changing the section, for simple and easy cleanup. Take a look at it and if you have any doubts let us know. Happy Tweening!
    1 point
  29. Hi, Maybe you're not queuing your scripts properly in Wordpress? I know very little about the subject but you should check this guide and it's resources in order to see if that helps: Hopefully this helps. Happy Tweening!
    1 point
  30. Hi, I'm working on an example for this. It's taking a bit longer than expected so please stand by. In the mean time I can tell you that you don't have any of the code regarding the panels animations and your CSS Setup is really the one you need to emulate the example you post. Happy Tweening!
    1 point
  31. Are you looking for something more like this?: https://codepen.io/GreenSock/pen/JjBBKdp?editors=1010
    1 point
  32. Just to throw my two cents out there - some CodePen accounts to bookmark and/or follow. Talented coders that feature a ton of GSAP: Cassie Evans: https://codepen.io/cassie-codes Blake Bowen: https://codepen.io/osublake Carl Schooff: https://codepen.io/snorkltv Pete Barr: https://codepen.io/petebarr Steve Gardner: https://codepen.io/ste-vg Ryan Mulligan: https://codepen.io/hexagoncircle Tom Miller: https://codepen.io/creativeocean Chris Gannon: https://codepen.io/chrisgannon Darin Senneff: https://codepen.io/dsenneff Craig Roblewsky: https://codepen.io/PointC/ (this guy is awesome 🤣) It may not be exactly what you need, but there should some good inspiration in those accounts. Happy tweening.
    1 point
  33. Yep, @OSUblake is correct - there's no reason to kill() an animation that has completed. GSAP already frees things internally for garbage collection by default (after the animations have completed). There's no benefit whatsoever to adding an additional kill() call manually.
    1 point
×