Jump to content
GreenSock

Leaderboard

Popular Content

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

  1. Looks like the flickering issue goes away if I add "transform-style: preserve-3d" to all parents that have perspective set up, and adding overflow: hidden backface-visibility: hidden to elements that are being transformed. 🥳
    3 points
  2. Hello @amitr95 I think the problems you are having might just be related to the general processing of the code's logic you run inside your function, and not really to GSAP measuring the height incorrectly. Here is an approach, that is a bit different on the logic side of things, which works fine for me with regard to the height. I also added overwrite: 'auto' to the tweens, so GSAP can sort out conflicting tweens that might be created along the way. [Note: this approach is not meant to be 100% bullet-proof. It is mainly to show, that the height gets tweened to the proper value.] https://codepen.io/akapowl/pen/VwBqJmj Edit: Since getting the logic right for something like this can become a bit tricky, here's another example of your setup, using an approach by OSUBlake - which works a lot better. Hope that will help. https://codepen.io/akapowl/pen/BaPvXQM Based on this demo. https://codepen.io/osublake/pen/JYQqZr
    3 points
  3. Yeah, that's the thread I was going to point you towards. You can't use pinType fixed if you've made a custom scroller unfortunately, you're in transform world now. I've made a more minimal demo so it's easier for people to see and help. How does this behave for you? https://codepen.io/GreenSock/pen/xxJMRvN?editors=0110
    2 points
  4. Hi all, I want to thank everyone for answering my question 👍. As elegantseagulls proposed, I should declare the image in the creation of the object Here the solution if you are interested: const imageTempClass = 'image-temp-class'; const imageTempElement = document.querySelector('.temp-image img'); imageTempElement.className = imageTempClass; element.append(el);
    2 points
  5. Personally I would never have ScrollTriggers in ScrollTriggers. Just have one ScrollTrigger with a timeline animation. The best thing to do 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. Here I've forked your pen and removed all ScrollTriggers and disabled your first ScrollTrigger, so that I can focus on the animation and not worry about ScrollTrigger (yet), I've set up a default duration of 10 seconds, so that it's easier to watch the animation. Then I put everything on the timeline and use the position parameter to have certain tweens happen at certain points. For an explanation: duration * 0.25 will make sure that #p1 start at 25% of the timelines duration. I've updated your HTML and CSS (changed it to SCSS) to make my setup work better, so be sure to take a look at that. If you're happy with the animation you can uncomment ScrollTrigger to see how it works on scroll. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/QWBzevL?editors=0010
    2 points
  6. Sorry about the confusion there - I'll add kill() to the TypeScript definitions in the next release. That method exists, of course - it just wasn't in the TypeScript definitions file. You should be able to just ignore that warning for now.
    2 points
  7. Chrome and Safari. Yes, I disabled cache. After several hours of digging, I think I figured out what was causing that issue in your scenario and I don't think there's a need to add a feature like "don't refresh unless the size changes more than ___". Please try the beta version of the upcoming release (on CodePen/CodeSandbox/Stackblitz only): https://assets.codepen.io/16327/ScrollSmoother.min.js (you probably need to clear your cache) Does that work better for you?
    2 points
  8. If I'm understanding you correctly, I think a fundamental misunderstanding might be that you're unlinking the scroll position from the animation, making the animation go to a completely different spot and then enabling ScrollTrigger which re-links it to the scroll position but [maybe] you're expecting it to act as if it's not linked? Like @mvaneijgen said, it sure seems like the most intuitive way to handle this is to make the "auto-play" simply scroll instead of trying to unlink/relink things such that the animation plays in a way that's disconnected from the scroll position. What would you expect to happen if the user tries to start scrolling when the animation is halfway done? It just seems fundamentally problematic to be handling it this way. Or did I misunderstand something?
    1 point
  9. Perhaps the problem is that React 18 runs in "strict" mode locally by default which causes your useEffect() to get called TWICE! Very annoying. It has caused a lot of headaches for a lot of people outside the GSAP community too. .from() tweens use the CURRENT value as the destination and it renders immediately the value you set in the tween, so when it's called the first time it'd work great but if you call it twice, it ends up animating from the from value (no animation). It's not a GSAP bug - it's a logic thing. For example, let's say el.x is 0 and you do this: useEffect(() => { // what happens if this gets called twice? gsap.from(el, {x: 100}) }, []); The first time makes el.x jump immediately to 100 and start animating backwards toward the current value which is 0 (so 100 --> 0). But the second time, it would jump to 100 (same) and animate back to the current value which is now 100 (100 --> 100)! See the issue? In GSAP 3.11, we introduced a new gsap.context() feature that solves all of this for you. All you need to do is wrap your code in a context call, and then return a cleanup function that reverts things: // typically it's best to useLayoutEffect() instead of useEffect() to have React render the initial state properly from the very start. useLayoutEffect(() => { let ctx = gsap.context(() => { // all your GSAP animation code here }); return () => ctx.revert(); // <- cleanup! }, []); One of the React team members chimed in here if you'd like more background. We strongly recommend reading the React article at https://greensock.com/react Happy tweening!
    1 point
  10. It was a very deep edge case related to rendering a scrubbed animation during a refresh. It'd actually take a really long time to explain all the logic, but it was tricky to track down. Glad to hear it resolved things for you. As for when we'll publish, I can't guarantee anything at this point but you are welcome to use the beta version in the meantime. I can get you a non-trial version if you'd like (since you're a Club GreenSock member - 💚)
    1 point
  11. If you can't replicate it without React - Perhaps the problem is that React 18 runs in "strict" mode locally by default which causes your useEffect() to get called TWICE! Very annoying. It has caused a lot of headaches for a lot of people outside the GSAP community too. .from() tweens use the CURRENT value as the destination and it renders immediately the value you set in the tween, so when it's called the first time it'd work great but if you call it twice, it ends up animating from the from value (no animation). It's not a GSAP bug - it's a logic thing. For example, let's say el.x is 0 and you do this: useEffect(() => { // what happens if this gets called twice? gsap.from(el, {x: 100}) }, []); The first time makes el.x jump immediately to 100 and start animating backwards toward the current value which is 0 (so 100 --> 0). But the second time, it would jump to 100 (same) and animate back to the current value which is now 100 (100 --> 100)! See the issue? In GSAP 3.11, we introduced a new gsap.context() feature that solves all of this for you. All you need to do is wrap your code in a context call, and then return a cleanup function that reverts things: // typically it's best to useLayoutEffect() instead of useEffect() to have React render the initial state properly from the very start. useLayoutEffect(() => { let ctx = gsap.context(() => { // all your GSAP animation code here }); return () => ctx.revert(); // <- cleanup! }, []); One of the React team members chimed in here if you'd like more background. We strongly recommend reading the React article at https://greensock.com/react Happy tweening!
    1 point
  12. Me again... Did some more digging and turns out setting pinType: 'fixed' in my use case done the trick 👌 Found it here So smooth now! Thanks, Jack
    1 point
  13. Hello Rodrigo and thanks for your answer. Finally I found out that it was not a greensock problem. I had to check the URL change to trigger the animations when changing views. For those who have the same problem, I found this solution, which is not very elegant but works: function checkURLchange() { var newURL = window.location.href if (newURL != oldURL) { oldURL = newURL; setInterval(checkURLchange, 0); if (newURL === devHomePath) { animHome(); animLinksHome(); } else if (newURL === devAboutPath) { animAbout(); } } }
    1 point
  14. I'm not completely sure what you're asking. But I think your problem is that you have one element that is controlled by two ScrollTriggers and they will fight for control if the first one is not yet done and the other one is starting, so you either have to make sure the other one is done when the next one starts or make it one big ScrollTrigger that just triggers over the whole duration (this seems like the easiest solution) https://codepen.io/mvaneijgen/pen/GRBPbgr?editors=1010 You could also look in to the overwrite property https://greensock.com/docs/v3/GSAP/Tween/vars If true, all tweens of the same targets will be killed immediately regardless of what properties they affect. If "auto", when the tween renders for the first time it hunt down any conflicts in active animations (animating the same properties of the same targets) and kill only those parts of the other tweens. Non-conflicting parts remain intact. If false, no overwriting strategies will be employed. Default: false.
    1 point
  15. Welcome to the forums, @KeithMartell. Whenever I hear about something working fine in CodePen but not locally, and it's React, that's an immediate clue that you're probably getting bitten by the React 18 "double-useEffect() invoke" behavior. It's a React thing. And I bet you're not doing proper cleanup to make sure you're not accidentally creating multiple conflicting/duplicate ScrollTriggers/animations. I'd strongly recommend reading this article: gsap.context() is your new best friend in React It makes cleanup so simple. useLayoutEffect(() => { let ctx = gsap.context(() => { // put all your GSAP/ScrollTrigger code inside here! }); return () => ctx.revert(); // <-- cleanup! }, []); If you're still having trouble, just fork this Stackblitz React starter template and try to recreate the problem: https://stackblitz.com/edit/react-cxv92j?file=src%2FApp.js
    1 point
  16. I'm pretty late to the party, but there is also this old thread which covers the basics. With your filled paths in the name, you'll need multiple masks to make it work properly. We go over that technique in the thread. Happy tweening.
    1 point
  17. Hi, ScrollSmoother is not in the file you're using: <script src="https://cdnjs.cloudflare.com/ajax/libs/smoothscroll/1.4.10/SmoothScroll.min.js"></script> That is not a GreenSock tool so that's why you're getting that error. The library you're pointing to is this: https://github.com/gblazex/smoothscroll-for-websites ScrollSmoother is a bonus plugin that comes with a Club GreenSock membership: https://greensock.com/scrollsmoother/ You can still test it in your local environment installing the gsap-trial package: https://www.npmjs.com/package/gsap-trial Also you can try it in Codepen forking this: https://codepen.io/GreenSock/pen/aYYOdN Hopefully this clear things up. Happy Tweening!
    1 point
  18. Hi @bugsMaker and welcome to the GreenSock fourms! There is no issue in creating different ScrollTrigger instances for each animation as long as they don't animate the same properties. Here is a super simple example: https://codepen.io/GreenSock/pen/BaPvVzK Let us know if you have more questions and remember to include a minimal demo. Happy Tweening!
    1 point
  19. You can create a React Context instance and use that to communicate with the components as discussed in this thread: Here you can check the live example: https://stackblitz.com/edit/nextjs-hcqury?file=pages%2F_app.js,components%2Flayout-wrapper.js,context%2FSmootherContext.js,pages%2Findex.js Happy Tweening!
    1 point
  20. Hi @devRawnie welcome to the forum! I'm not completely sure on what it is you want to do, but if I understand it correctly you want to either have the animation play on scroll or do the exact same but on button click. Destroying ScrollTriggers and enabling them, can get really complicated, so why not keep it simple and just scroll for the visitor on button click, this way the animation is always the same and no need to destroy ScrollTriggers and enable them again. I've used the ScrollToPlugin to scroll to the end of the ScrollTrigger.end position, based on the timeline.duration(). Should do the trick right? Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/zYLyqMX?editors=0011
    1 point
  21. Great to have you as a student in Creative Coding Club! Definitely check out the lesson ScrollTriggers for Multiple Sections in ScrollTrigger Express. The video goes into great detail on how to loop through multiple elements, find child elements to animate, and control each section's animation with ScrollTrigger. I modified that lesson's demo to include a basic SplitText animation on the <h1> in each section https://codepen.io/snorkltv/pen/gOjZPEY?editors=1010 Side Note: if anyone around here is into 90's imports, a 1994 Supra just sold for $150,000 on BringATrailer.com
    1 point
  22. Hey @Cassie Wow thanks a lot for this solution, I missed this parameter when I was reading the documentation That works like a charm 🙌 Cheers
    1 point
  23. I may have found a fix to the problem simply by setting overflow-x: clip Just leaving that here in case someone else runs into this.
    1 point
  24. 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
  25. Gotcha! Thanks for that. You're after pinnedContainer pinnedContainer Element | String - If your ScrollTrigger's trigger/endTrigger element is INSIDE an element that gets pinned by another ScrollTrigger (pretty uncommon), that would cause the start/end positions to be thrown off by however long that pin lasts, so you can set the pinnedContainer to that parent/container element to have ScrollTrigger calculate those offsets accordingly. Again, this is very rarely needed. Important: nested pinning is not supported, so this feature is only for non-pinning ScrollTriggers (added in 3.7.0) You have a strange 200px gap at the bottom because of your start values which were adding a 200px offset. Here you go, like this? https://codepen.io/GreenSock/pen/LYBXQbw?editors=1010
    1 point
  26. 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
    1 point
  27. 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
  28. 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
    1 point
  29. im trying to create this animation but its glitching for some reason i cant find, i tried to add delay: and then i use "<+=2.5" but its not working, sometimes it work if i dont move my mouse too much. please can anyone tell me where i made mistake or is this is the wrong way of making this timeline. thank you
    1 point
  30. I second every thing you say and would love to point out some other points: I started wed-dev in 1995 when we really had to count each byte by hand, and I stayed old-school in that regard since then. Nevertheless I find it somewhat laughable when I hear people arguing about half a kilobyte when we talk JavaScript or CSS Files, while they deliver images upwards of 3MB. Using image src-sets and carefully compressed images for several screen-sizes and resolutions will often gain you hundreds of kilobytes, going for webp if target permits it might add to this. Wise choices in pre- or lazy loading could use the thoughts wasted on the choice of minifier. Minifying most of the time isn't worth it in my experience, as all servers send gziped anyhow - I even had situations where not minified files performed better, as gzip was struggling with minified ones. (exotic I admit) Tree shaking is another thing that in most cases isn't necessary if you carefully consider what you really need upfront and if you refrain from using complex libraries for just one simple functionality. (Don't get me started on that one. Yet.) Also oftentimes I find it preferable to load a little extra with the front-fage or any other landing page, (like style instructions for following pages inside one slightly larger CSS of an icon-font) as the user usually has to wait for that shiny impressiv frontpage anyhow. As he has to load everything site related from scratch - a few milliseconds more or less don't make a difference. Once the user moves on our site, she gets a better and more snappy experience with all that is already cached. First and foremost the whole fetichism about every single kilobyte in tools like GSAP in my opinion stems from people loading half a million useless and sometimes conflicting libraries under the pretense of 'not reinventing the wheel' while they are actually to lazy (?) to write a little code on their own and learn the basic concepts. To compensate for their overuse of tools the use more tools to tree shake minify and whatnot them. Ending up with complex websites, complex workflows, thus forever forced to care more for their tools instead of their product. *old man stops ranting* That said GSAP is probably the only library I'll use without a second though - it is worth every kilobyte in gold and double that.
    1 point
  31. Removed yarn.lock file worked for me!
    1 point
  32. Hey there! A timeline might not be what you're after? Are you trying to make the images small when the cursor movement stops and then show them as the mouse moves around? If so, you might want to hook into the velocity and then adjust the size of the images depending on how fast the mouse is moving. This really isn't a great implementation, it's a buggy and I don't think movementX and movementY can be used in older browsers - but it might point you in the right direction! https://codepen.io/GreenSock/pen/oNGpYLY?editors=0010 You also might like to look at quickSetter... https://codepen.io/GreenSock/pen/WNNNBpo
    1 point
  33. And here's an example of a particle fountain using the Physics2DPlugin.
    1 point
×