Jump to content
Search Community

Leaderboard

  1. mvaneijgen test

    mvaneijgen

    Moderators


    • Points

      2,044

    • Posts

      2,514


  2. Rodrigo test

    Rodrigo

    Administrators


    • Points

      1,380

    • Posts

      6,318


  3. GreenSock test

    GreenSock

    Administrators


    • Points

      1,159

    • Posts

      23,069


  4. Cassie test

    Cassie

    Administrators


    • Points

      732

    • Posts

      4,839


Popular Content

Showing content with the highest reputation since 03/29/2023 in all areas

  1. What a year! Such an honour to be able to serve this inspirational community. Thanks to all the moderators and helpers in these forums for their unwavering efforts and assistance in 2022. Here's to another wonderful year of creativity and adventures!
    10 points
  2. It's showreel time! 2023. What a year. As always, blown away by the creativity and skill in this community. Here's to another amazing year of animation magic in 2024. ✨
    9 points
  3. I'd recommend investing in a Club GreenSock membership so you have access to SplitText. Makes this animation fairly easy. Split into chars. Grab the innerText and place it into 2 identical divs in each char div Set parent char div overflow to hidden Move the clone yPercent -100 or 100 depending on odd/even in the array Animate the 2 child divs yPercent +=100 or -=100 again depending on odd/even in the array Set tween repeat to your liking Place the tweens on a parent timeline (optional) and animate the progress Each column is its own tween so you can randomize or offset the times a bit if you need a more organic feel. Always lots of options with GSAP. https://codepen.io/PointC/pen/ZEmOKvP Happy tweening.
    9 points
  4. run into similar issue using the app directory in NextJS 13. I'm using ScrollTrigger and ScrollSmoother plugin and managed to fix it by moving the gsap.registerPlugin(ScrollTrigger, ScrollSmoother) inside of useEffect/ useIsomorphicLayoutEffect hook. hope this helps
    8 points
  5. I was so impressed by this technique I created a simplified demo to illustrate how just one letter's animation works. I thought for sure each character would have been duplicated multiple times. https://codepen.io/snorkltv/pen/dyQXqJr?editors=0010 Great job @PointC!
    7 points
  6. 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.
    7 points
  7. SVG Mask The most simple solution is to create a mask with SVG and adding the image to the SVG file it self. Although this is a simple solution it is probably not going to be bullet proof, because your images probably come from somewhere else and you’re not going to hand craft all these images inside your vector program, but I want to show that this is possible and is indeed the most simple solution. https://codepen.io/mvaneijgen/pen/xxMBVqX CSS Clip-path If you have a relative simple shape you could use a CSS clip-path to mask your shape. There are a few gotchas, but if you keep them in mind this will be the most robust option. Personally I use https://bennettfeely.com/clippy/ to create my clipPaths and the first gotcha is that you have to animate between shapes with the same amount of points (if you’re familiar with MorphSVG you know why this is). Another thing to keep in mind is that when animating complex strings with GSAP is that the strings should be as much the same as possible, see this example below // Example, our starting string polygon(50% 10%, 75% 17%, 98% 35%) // ❌ Bad, not the same amount of points and diffrent suffixes polygon(50% 0, 18% 12%, 66% 29px, 98% 35%) // ✅ Good, same amount of points and everyhting is suffexed with a % sign polygon(50% 0%, 18% 12%, 66% 29%) https://codepen.io/mvaneijgen/pen/MWLxyPp SVG Mask but on normal tags A really weird but really useful solution is creating an SVG that is 1px by 1px. Yep, you heard it write a 1x1 SVG. Everything with in the 0 - 1 pixel space will gets stretched over your image (if you give your clipPath the following tag clipPathUnits="objectBoundingBox”) and you’re golden, I’ve learned this from Dave Smyth over at https://davesmyth.com/clip-path-scaling where he has an even more in depth look on how and why this works, recommend giving it a read if you want to go this route! https://codepen.io/mvaneijgen/pen/jOdJGQ Hope it helps and happy tweening! Some extra resources you could take a look at. Organic Morphing: Getting needed points from Adobe Illustrator — motiontricks SVG Masks and clipPaths — motiontricks GreenSock SVG Ripple Mask Effect — creativecodingclub Easy SVG Masking — creativecodingclub Clip-path scaling — davesmyth.com Extra example With this last example you can create really elaborate effect with just a few simple shapes. The example below uses the exact same timeline animation for each of the clip paths with some clever use of the stagger object.
    6 points
  8. I hope this is allowed, as I didn't see any rules against it in the forum guidelines, but I felt compelled to write this out after wrapping up a massive feature my dev team has just completed using GSAP. I don't know if anyone will see this but I wanted to give a massive thank you to everyone on the GSAP team, from the devs working to support the platform to the devs who are incredibly active, kind, cheerful, and helpful in the forums. In my career I've never come across a third-party library that has the kind of support and community that GSAP has, and I wanted to say thank you to every single person who works on this project. It seems to be a real labor of love, and the entire internet is a better place because of you and this project. Learning and using GSAP over the past few months has truly been a delight. The documentation is wonderful, the forums are deeply educational and the responses from the community team and devs have been invaluable resources. So good, in fact, that I never had to make a post here, and have been able to solve every issue I've come across by searching through these same forums. Every time I think I've pushed the platform to its limits, and encounter an issue that at first glance seems impossible to solve, Green Sock has somehow already thought of it and supplied a simple solution.
    6 points
  9. I think you're seeing the default ease of power1.out that gets applied to every tween in ScrollTrigger by default, see https://gsap.com/docs/v3/Eases/ and also check out the video our own @Carl dropped just a week ago! Here the same pen with the ease set to none which makes it an even speed through out the whole animation. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/abXxXo
    6 points
  10. Hi @newguy123, @mvaneijgen and @Toso are right, the level of support doesn't change because of the subscription status. I assume that you want to know why sometimes we don't create fully working solutions for our users, as Mitchel points is mostly a time related problem. Let's say that a user wants to create a content slider with a series of features and I'm up to the challenge. Creating a complex content slider is a really time-consuming task and, being optimistic about it, it takes me 6 hours. That's almost a full day of work where I can't address any other questions in the forums or any of my other obligations. Then I do the same for another complex problem for another user. Sure enough we love challenges and helping but most likely I will use two full days in order to solve two complex issues while more and more questions pile up in the forums and several other users don't get support. See the problem? Another thing to keep in mind is what can be considered as support. For us supporting our users is clearing API questions, GSAP usage doubts and obstacles, but not resolving complex problems. Normally we see a lot of questions in the forums that are not really GSAP related, but that can be resolve quite quickly, like an issue with HTML structure (like layouts for example) and or CSS that is causing the problem, but we nudge the users in the right direction if catching the problem doesn't involve a lot time. Other times we see users getting into project that are really challenging without having enough knowledge about HTML/CSS/JS and GSAP in order to create what their trying to do, and they want a copy/paste solution for their problem and/or need. Web development, as any other career choice, requires a learning path believe me. I've been doing this for over 10 years and I'm still learning on an every day basis. For example if you want to become a professional in construction you can just jump into building a 10 story building, perhaps start with some wood and screws to build a tool shed or something like that and get more knowledge on the craft and keep improving. There is a learning curve for everything in life and is important to recognize that, be constant with it and dedicate time and effort to it. Happy Tweening!
    6 points
  11. Yep! You're missing the best bit about SVG. It's already responsive. Hooray! viewBox="0 0 550 800" - this is the unit space you're working in. You don't need to calculate viewport widths, elements inside an SVG exist in SVG space, not browser viewport land. Your SVG is 55O SVG UNITS wide - always. No matter how wide the browser window is. If the SVG itself is 50px wide, it will be 550 SVG units wide. If the SVG itself is 500000px wide it will still be 550 SVG units wide. All you have to do is set the SVG itself to be 100vw (or whatever width you want it to be) and then animate elements inside it based on the viewBox. That's all. You've fallen into an over-engineering trap. ? viewBox="0 0 550 800" // width in SVG units is 550 tl.to("#pattern-1 rect", { x: 550, // so animate by 550 SVG units. Simples. ... }) --- Also, big warning about this part - You're creating a timeline, then adding some tweens to it. Ok. All good.... But then you're adding two more tweens on every resize event. Resize events don't just fire when you finish resizing the browser, they fire CONSTANTLY. You're adding hundreds of tweens on resize here. var tl = gsap.timeline({ duration: 1, ease: "power1.inOut" }); function staggerPix (){ let innerWrapper_width = innerWrapper.offsetWidth; let distance = innerWrapper_width - patternW; tl.to("#pattern-1 rect", { x: distance, yoyo: true, repeat: -1, stagger: { each: 0.1, from: "random" }, onUpdate: console.log("onUpdate: " + distance) }) .to("#pattern-2 rect", { x: distance, yoyo: true, repeat: -1, stagger: { each: 0.1, from: "random" } }).progress( 0.2 ); } staggerPix (); $(window).on( 'resize', function() { // aaaaaaaah. You're adding hundreds and hundreds of tweens to the timeline on resize staggerPix (); }); aaah.mp4 If I log them out you can see! How many tweens you're adding. ? Here's a simplified responsive version https://codepen.io/GreenSock/pen/jOXOerz?editors=0010 Hope this helps!
    6 points
  12. Hi @Mumm-Ra. Thanks for the suggestion - are you basically asking us to make GSDevTools "frame-based" instead of "time-based"? The problem with that is GSAP is inherently resolution-independent in terms of timing, and that's a GOOD thing. In the old days, a lot of systems were frame-based, so for example you might make an animation that linearly travels 600px between frame 10 and frame 70, so 10px per frame. Seems fine initially, but what if you run that animation at a timeScale of 0.25 (quarter-speed)? Since that animation was frame-based, it's resolution-dependent, meaning it only has 60 frames worth of motion and if we now slow the playback speed, it looks a lot more jerky. GSAP, on the other hand, is resolution-independent in terms of time, so if you timeScale(0.25), it'll adjust perfectly and the motion will be totally smooth. It's not locked to moving 10px per frame like in the frames-based animation. And remember that even if requestAnimationFrame() is supposed to run 60 times per second, sometimes it doesn't. The system could be temporarily bogged down. In a frames-based system, that would mean the entire animation would take longer to finish. For example, if the system was working really hard and the frame rate dropped to 30fps, that 60-frame animation would take 2 full seconds to complete! But with GSAP, it'd still honor the 1-second duration; it'd just move a longer distance on each frame. All that to say that I do not believe it would be a good idea to make GSDevTools frame-based. It may give the false impression that GSAP works that way. A developer might intricately build out an animation such that a particular element starts moving in exactly frame 62...but then in the real-world browser on a system that's much less powerful, it may actually end up firing on tick 41 instead because the frame rate dropped. Why do you need things to be frame-based? What is difficult for you about using time (seconds)?
    5 points
  13. Stop optimising your code before it is even working! I have to preface this with I do this all the time, but knowing helps me get out of this thought process. I see so many questions on this forum “how do I do this in a for loop, but then not for the third item in the loop…”, you're making it way to complex. I know we all have learned Don’t Repeat Yourself (DRY), but there is nothing wrong with a little repeating if you know you're going to optimise it later. When I feel I’m banging my head against the wall and can’t see how the get something to loop the way I want, I take a step back and just manually write it out by hand. Literally writing out what each element should do, this of course can be insane if you need to have more then a hundred elements to do something, but then I just pick the first few, eg .item:nth-child(1), .item:nth-child(2), … .item:nth-child(5),ect. If you do this a few times you’ll probably see a pattern emerging, but try to resist the urge to start optimising, just keep writing out the animation until you have a solid base that represents the animation you want to have. That is why I love working in Codepen, first I don't have to worry about my real projects dependancies, or my framework throwing weird errors, I can just worry about the demo I’m building and making it the best I can and when I think I’m ready for the next step I fork my pen and start moving the code around. Get some of the repeating code and try adding it to a for loop, then test if it is still doing what it was doing when it was written out by hand. Below some code examples from a real world project of mine, where I was “I don't even know how this would work!” and you can see my first demo was no where finished, I had over a hundred lines of animation code! https://codepen.io/mvaneijgen/pen/YzgVKRo Then I forked the first version and started to optimise a few things, swapping out fixed values for dynamic once, but still going on writing each tween out by hand, there even more lines of code now! https://codepen.io/mvaneijgen/pen/gOEWYZp In version 3 I finally found that I had the animation down like I want it, it could still use some fine tuning, but all the logic was there. Two hundred lines of code! https://codepen.io/mvaneijgen/pen/dyrRrvL And finally reducing that amount of code to just fifty lines by optimising what was already working and removing the duplicated code and adding it to a for loop. This is just an example, it might not even be the final code, but it is working! So now I can worry about accessibility making it responsive and making it fancy. But it's to illustrate that I could never come to the same conclusion that I’ve come to now if I had started with trying to optimise the code from the start. Personally I need to get a feel for what the code needs to do. Working in Codepen and forking your work is such a life saver, because you can fall back at earlier versions when you inevitably brake something, not to talk about GSDevTools what an awesome tool to debug an animation (🫢 did you know you could just use that paid plugin, even if you’re not a member on Codepen for free!) If you can do this at your first go writing out a project, why are you even reading this?! And we love to have you helping around here on the forum, it is great to have such a keen eye help out!
    5 points
  14. Sorry, I'm not sure I can edit it so that you easily understand it. That's why I spend hours creating video lessons that explain everything in detail. However, this is what the edited code would look like: https://codepen.io/snorkltv/pen/wvOyeYO?editors=0010 Good luck with the rest of your project
    5 points
  15. Another option when adding multiple targets to a motionPath: You can stagger the start times and advance the tweens to the full duration or add individual tween to a master timeline. This would be in lieu of using the start/end values. in the motionPath object. Just my two cents to keep your code DRY. Happy tweening. https://codepen.io/PointC/pen/ExVzqdm https://codepen.io/PointC/pen/pojmBKJ
    5 points
  16. Ok. So literally two weeks ago I didn't know what Nuxt was, but thanks to the wonderful people in this forum, they have helped me get to this stage. My new site in progress with seamless Nuxt3 Page Transitions: gsap.windpixel.com.au. But back to your problem, I added this css into the style.css file to allow both entering and leave pages to be overlapped. They get added into the DOM at the same time, so by default, they stack giving un desirable effects. Here is a working demo for of yours with seamless transitions: https://stackblitz.com/edit/nuxt-starter-sxwssz?file=helpers%2FtransitionConfig.js .page-transiton-enter-active { position: fixed; height: 100%; width:100%; top:0; left:0; right:0; bottom:0; z-index:9; } .page-transiton-leave-active { position: fixed; height: 100%; width:100%; top:0; left:0; right:0; bottom:0; /* z-index:4; */ } I added back the logic to track when page transitions are starting and ending, this is vital to the site working as you need to fire and cleanup certain things when the pages are done. I also made a const to handle the duration for enter and leave, these should be the same so makes sense to tie them together. import gsap from 'gsap'; import { useTransitionComposable } from '../composables/transition-composable'; const { toggleTransitionComplete } = useTransitionComposable(); const duration = 0.6; const pageTransition = { name: 'page-transiton', mode: '', onEnter: (el, done) => { gsap.set(el, { yPercent: 100 }); gsap .timeline({ paused: true, onComplete() { toggleTransitionComplete(true); done(); }, }) .to(el, { yPercent: 0, duration: duration}) .play(); }, onLeave: (el, done) => { toggleTransitionComplete(false); gsap .timeline({ paused: true, onComplete: done }) .to(el, { duration: duration }) .play(); }, }; export default pageTransition; I hope that helps. If your journey is anything like mine, you will encounter quite a few problems to solve, but once you get past that, full page transitions are amazing! - Lance
    5 points
  17. Welcome to the forum, Simon. You can disable automatic rounding via autoRound - that should help. https://gsap.com/docs/v3/GSAP/CorePlugins/CSS#autoround https://codepen.io/akapowl/pen/ZEPGRNa
    5 points
  18. My team and I build about a dozen banner ads a week. We just do straight HTML/js, we haven't found a graphic banner tool worth the trouble. We rely on gsap timeline and Google fonts, neither of which add file weight because of the CDN. Most of our file weight is graphics unless we add a gsap members files and those only add a KB or two. Coupled with how awesome Greensock tutorials are and their response on this forum is we are getting by like bandits. With that said it is my opinion that if you do as many banners as we do straight HTML is the way to go, if you only do one a month I would use Google Web Designer but I would also quit my job.
    5 points
  19. Hi @lizettevanboom and welcome to the GSAP forums! In order to make the Endless Loop helper function work properly with elements with different widths, you have to wait for all the elements to be loaded. In the case of HTML media elements you should wait for the loadedmetadata event: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/loadedmetadata_event The Horizontal Loop Helper will handle the elements regardless of their widths, sure most demos use elements with regular known dimensions, but is not at all a constraint. So when the metadata of all the videos are loaded you can create the instance of the Horizontal Loop: const videos = gsap.utils.toArray("video"); const totalVideos = videos.length; let loadedVideos = 0; videos.forEach((video) => { video.addEventListener("loadedmetadata", () => { loadedVideos++; if (loadedVideos === totalVideos - 1) { // all the videos are loaded, create the Horizontal Loop } }); }); Hopefully this helps. Happy Tweening!
    5 points
  20. You'll be getting the exact same support! We like to help everyone on these free forums, but it is always nice to see questions asked by paid members. I like it not to influence me, because you never know the situation of the person, but seeing a user asking a lot of questions and not supporting the tools feels a bit weird, but extending our help we always hope that the person comes back and will reciprocate the support they are getting. (to emphasise, I'm just a volunteer moderator on the forum and this is my personal opinion) If you feel up for the challenge you can always help around here on the forum, that is how I started and I really got a lot out of it while asking my own questions I started helping out others and this really kicked start my understanding of the tools!
    5 points
  21. Oh, that wasn't clear from your first description. Then is a timeline even a better idea. I would create the animation you want to happen on the timeline and then just restart the timeline every time someone enters the ScrollTrigger. I've removed all the comments and placed new once. The start animation is still the same, it animates from 0 to 1 with no ease, then the timeline does nothing for 1 second (change this to how long you want to see it) and then it animates to 0 again. The ScrollTrigger plays this animation when the ScrollTrigger start triggers meet (the green once), the end triggers will do absolutely nothing in this example (the red once), so ignore those. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/NWoBbEe?editors=0010
    5 points
  22. Hello @Gnekr That SVG looks very much like the SVGs in these other threads a couple of weeks ago. As was already mentioned in those threads, what you're trying to achieve is entirely possible, but will not be simple at all, which is why that is quite a bit out of scope of what to expect as support from these free support forums; especially if you do not provide anything you have tried yourself that we could offer hints or advice on - please read the forum guidelines. Key to getting something like you intend done, is understanding how SVG works in the first place, so you can then go on and tinker with values that might be relevant for your expected animation goal. https://developer.mozilla.org/en-US/docs/Web/SVG There will be many, many things you will have to keep an eye on, so if I were you, I would start simple and work my way up the complexity from there. With regard to how exactly you want things to behave it might be better to re-work your SVG so it's easier to manipulate to get the exact effect going, that you aim for (as also mentioned in the linked threads). Below is a rather basic example just to help get you started with something - not intended to serve as a working solution for you. Note: I used the .getBoundingClientRect method to get the dimensions I need to map to the SVGs dimensions, just because it works for me. This likely might not work for your setup, and you may have to use some other way to determine the dimensions you need to work with. https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect https://codepen.io/akapowl/pen/eYxRovy What will probably come in handy, is having a look at GSAP's utility functions, especially mapRange. https://gsap.com/docs/v3/GSAP/gsap.utils/ https://gsap.com/docs/v3/GSAP/UtilityMethods/mapRange() I didn't use it in my example, but you could also have a look at GSAP's Observer, as an alternative to the plain eventListeners I used... https://gsap.com/docs/v3/Plugins/Observer/ ...and GSAP's .quickSetter() or .quickTo() for setting / tweening the values on mousemove. https://gsap.com/docs/v3/GSAP/gsap.quickSetter()/ https://gsap.com/docs/v3/GSAP/gsap.quickTo()/ Also it might help in the long run for getting a better understanding of how to animate SVG to have a look at https://www.motiontricks.com/ I doubt you will find an exact example of what you're aiming for there, but it offers some neat tutorials and great general advice on how to best work with SVG when animating. Beyond that, if you have any questions directly related to GSAP, also please keep it simple instead of listing a bunch of requirements that you expect others to provide a full-fledged solution for. This forum is not intended to give out custom crafted code examples to anyone asking for it, but to help with problems encountered when using the tools provided. Stitching the little pieces together and developing the logic behind that to achieve your goal, will be yours to do. And as also mentioned in the other threads already; If you see no way to achieve something like that yourself, you might want to explore paid consulting options with GreenSock by reaching out to them directly, or as an alternative you always have the option to post in the "Jobs & Freelance" forum to try and hire someone else that can help you with your tasks. Good luck with the project! Edit: Here's that same example using multiple paths, just to give you a better idea for your more complex scenario. https://codepen.io/akapowl/pen/QWYgeXO
    5 points
  23. Hello @Solbeg What Mitchel said actually isn't 100% true - ScrollTrigger does have a built in porperty to match cases like yours, where you are pinning the parent element of your trigger element multiple times - it's the pinnedContainer property. This is from the ScrollTrigger docs: 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) That should fix your issue without a lot of custom code, but instead handled by ScrollTrigger internally (gotta thank GreenSock for that). Does this work better for you? https://codepen.io/akapowl/pen/ExGEBpm
    5 points
  24. Hi and Welcome to the GreenSock forums, Thanks for the demo. It seems you might want to take a few steps back here and get 1 card to flip the way you want before you worry about a lot of cards or even hooking up ScrollTrigger. Here's a demo from one of my courses, perhaps it will help you get your cards setup in a simpler fashion https://codepen.io/snorkltv/pen/VwKGVjb?editors=0010 And to add ScrollTrigger you can do something like this https://codepen.io/snorkltv/pen/gOZWaQj?editors=1010 Hope this helps. If you want to learn GSAP inside and out, check out my complete GSAP course bundle, it will guide you through all this and so much more.
    5 points
  25. Hi and welcome to the GreenSock forums, Typically it is best to provide a minimal demo showing what you have attempted. This way we can help guide you. However, I had recently shared this demo with my students, perhaps it will help you get started. https://codepen.io/snorkltv/pen/QWJNmQb?editors=0010 If you need help learning ScrollTrigger be sure to check out my comprehensive GSAP training.
    5 points
  26. Hey, as promised here is my approach (only thing left is some match media stuff, to catch mobile users and adjust the sizing). codepen Unfortunately, I had to rewrite it a bit because I couldn't find a circle image for my mask-image and uploading assets is a codepen pro feature.... In the end I could have used a clip path, but I wanted to stick with what I already had, would probably have been the same result. It would be interesting to know which approach is more efficient (probably someone knows it and could enlighten us), but I will leave it for another day until I notice some issues. @Rodrigo nice catch with the quickTo(), didn't even notice they weren't using it . Hope this helps someone in the future and as always feedback is welcome.
    5 points
  27. Hello Elicrespo. I don't think any of this is GSAP related - it's more about SVG, layout in general and CSS styling. We actually like to keep this forum focussed on questions about GSAP, but here are some pointers. If I am not mistaken, you don't see the 'orange' ball because it is set up as a mask - technically it isn't orange at all. I can not give you a proper explanation for this, but if you want it (the mask) to show what it does the other sections, you will probably have to give your .svg_40vh a background-color - in the fork below, I added the same as is on your ._100vh Maybe the MDN docs can help understand better. https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask It is not - your SVG sits on top of it - you said it yourself here: For it to be clickable it is not important that the SVG sits on top of it - you are not somehow replacing your OS's mouse-cursor by moving around an element to imitate cursor movement. And actually the SVG sitting on top of your div is what makes your div not clickable because it now sits between the actual cursor and the div that you want to click on, so the OS's cursor's clicks can not get through to that element. You can see that by right clicking the area you want to click and select 'Inspect element' (or something along those lines) and it will make dev-tools pop up and in the DOM structure tree show you which element it is you have selected. To work around that problem, I set pointer-events to none on the whole SVG via CSS in the fork below, and only set them to auto on the elements that you actually need/want pointer-events - i.e. your ._100vh elements. I hope that works more like you had in mind. If you have any more GSAP related questions, let us know. https://codepen.io/akapowl/pen/xxmOoPa
    5 points
  28. Hi and thanks for the demo. A yoyo is added when you need a repeating timeline to animate forwards and backwards the same way. If you want to do something different in the reverse direction then using yoyo isn't going to be a manageable solution. From looking at the code you provided it looks like it's a bit over-engineered for something that should be a bit simpler. Unfortunately I'm really not following exactly what should happen. In a case like this I would suggest you build a single timeline that ONLY plays forward and clearly shows how everything should appear and disappear. Put all the tweens in the timeline and don't use any function calls or conditional statements to build the animations. At that point we can look at it and see common patterns and then advise you on how some of it can be optimized with functions that return timelines or loops or whatever. While reading your description it kind of reminded me of this lesson from GSAP 3 Beyond the Basics where dynamic content shows and hides throughout a timeline. Perhaps something like this will help https://codepen.io/snorkltv/pen/XWmdPBv
    5 points
  29. Hi @Adriano Resende welcome to the forum! If you have animations that are dependent on other animations I find it better to use a timeline. I've did a quick hack in your code and used one timeline and ScrollTrigger to control all tweens. I've also set scrub: true so that the whole timeline gets stretched over the scroll duration, maybe that is not what you want. (see another solution below) https://codepen.io/mvaneijgen/pen/bGOpXmm?editors=0010 ScrollTrigger uses the native scroll, maybe that is not what you're looking for, have you seen the Observer plugin https://greensock.com/docs/v3/Plugins/Observer, this can watch for scroll events and do something based on that logic, as you can see below you can scroll as much as you like, but it will only ever go to the next slide if you scroll after the first 'section' is done animating. https://codepen.io/GreenSock/pen/XWzRraJ These are some routes to go it is up to you what solution fits best with your requirements, but these are two routes I could think of on the top of my head. Hope it helps and happy tweening!
    5 points
  30. Hi @jayesh24 there is no need to post your question in multiple places. I've removed your comment on the two year old topic Let's start with one question at a time. What I've done to your tweens is put them on a timeline, now they will play in sequence with each other, this is not what you want, but with the powerful position parameter you can tell certain tweens to play at certain points. Your first tween takes 30 seconds which is 100%, some quick, math 30/100 = 0.3 * 40(%) = 12, so you scale animation should take 12 seconds. I have it start at the same time as the previous tween (with the position parameter "<"), this also includes the opacity (if you want some other logic you could create a separate tween that does the opacity, but also starts at the same time ("<"). Then your last tween starts 2.5 seconds of the whole on timeline. I think this all is a lot easier to manage than doing single tweens with delay calls. Timelines are the best part of GSAP in my opinion. https://codepen.io/mvaneijgen/pen/NWexyYN?editors=0010 I'm not sure what you want with your other question, can you maybe rephrase it and pick one of the options you want to explore?
    5 points
  31. Hey, when something is out of place, it's often related to basic html/css structure. If you use position: absolute, you need to define anchors to keep it in place. So I added them to your .dot class in the css file and it looks fine to me. codepen For clarity, I reduced the size of dotQuantity (line:24 in js) because I didn't need it that high for my purpose. You can set it back to 1250. Also, there are some guides on how to center elements using CSS. And last but not least, your codepen uses an outdated syntax of gsap, so I can recommend you to have a look at the migration guide. Hope this helps you to continue further and good luck with your project
    5 points
  32. ok, this turned into an afternoon of distraction After doing it first with MotionPath, I had a hunch it could be done with some math and experimentation so I came up with this https://codepen.io/snorkltv/pen/jOQgKWX?editors=0110 The circular motion is caused by offsetting the transformOrigin. It's pretty good. However you will always have to play with the duration of the animations of the arcs vs the straight part as it can look bad if there is an abrupt change in speed. Ultimately (as @mvaneijgen suggested) MotionPathPlugin is way cleaner as it: will only require one tween speed is automatically kept consistent throughout I think most people think of MotionPathPlugin as only good for SVG animations, however it excels at applying SVG path data to HTML objects! In order to figure out the path for an html element I created a similar svg rect with rounded corners converted that rect to a path with MotionPathPlugin used that path to animate a div circle around my div button https://codepen.io/snorkltv/pen/BaGXxrd This demo here copies the path value from the pen above and applies it to the div button. I did this to show that you don't really need an svg in your final html page https://codepen.io/snorkltv/pen/jOQgKNe?editors=1010 If you have buttons of different sizes you could use these files as guides to create a script to dynamically generate all the assets. If you are handy with SVG path data you could also use the dimensions and radius of your button to dynamically create your own paths. Somehow I feel there's some room for some future creativeCodingClub.com lessons here.
    5 points
  33. The best way to learn is to get your hands dirty, so try somethings out your self and post back here with the minimal demo's you've made. Personally I use codepen to try out new ideas, I usually then just keep forking my pen to try out different ideas, either because I think it could be better or my original idea was not working. Usually at version 10 I got something I'm happy with. Creating forks of your pen will allow you to fall back at earlier ideas if something new is not working.
    5 points
  34. Welcome to the GSAP forum @Chiggsy What have you tried so far? Steve is right, since gap uses numeric values, it should easily be animatable. Here is an example - note, that I set autoRound: false here, to smoothen things out a bit. https://codepen.io/akapowl/pen/gOQwgJZ https://greensock.com/docs/v3/GSAP/CorePlugins/CSSPlugin autoRound By default, CSSPlugin will round pixel values and zIndex to the closest integer during the tween (the inbetween values) because it improves browser performance, but if you’d rather disable that behavior, pass autoRound: false in the CSS object. You can still use the SnapPlugin to manually define properties that you want rounded.
    5 points
  35. Hey @AntonioNB4, I've put some comments in your javascript code with explanations. The first thing is I don't see any use for more timelines, this can all be just one big timeline that plays in order. I would either use the position parameter or delays not both, I'll think if you use both you'll will get lost faster on what is influencing what tween. Instead of yPercent (which uses the height of the target element) I've used just the y: property. In there I use a function based value which gets the height of the parent (#preloader) and the height of the target element, then half that value, because you're item is already in the middle and moves that element, this is just basic math to get the pixel value the element needs to move. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/bGQVXVW?editors=0010
    5 points
  36. For example... https://codepen.io/GreenSock/pen/YzRXjYK
    5 points
  37. Hi @Sveninyo, Personally when working with ScrollTrigger I 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. So here is a fork of your pen with ScrollTrigger disabled and just a timeline with the animations. I've moved the background tween to the front, because I would think you want to start with that. I've kept the same stagger for both tweens, but I've set the yPercent tween to start at the stagger amount. https://codepen.io/mvaneijgen/pen/MWzwbPp?editors=0010 Then it is just enabling ScrollTrigger again to get everything to work on scroll. You rarely need more than one ScrollTrigger to get the desired result, just a rule of thumb to keep in mind when building new ideas. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/abQOBQq?editors=0010 If you want to learn more about staggers and how you could do some powerful things with them check out our own @Carl's YouTube channel. There you can learn the same logic I've used with the offset staggers!
    5 points
  38. Hi @ErwinHeiser welcome to the forum! I wanted to jump on on top of @Carl's feedback with the following pen. DrawSVG can animate strokes, and your current paths don't have strokes only a fill color. As you can see below all your paths have two strokes around the path. If you want to animate something like this you have to redraw them with without a path and only one line with something like the pen or pencil tool from Illustrator, than I think it will look like you want it to. Oh and I also have removed pathLength="1" from the svg, never seen it before and don't know what it is doing and with it looked like it wasn't working. Hoop dat het helpt en veel geluk! https://codepen.io/mvaneijgen/pen/oNarmbv?editors=1010
    5 points
  39. Yeah, I'd have to disagree on this. If I add a set tween to the beginning of a timeline I expect the timeline to start at that set state. It's an explicit instruction to immediately set a value. It's not saying 'animate to' Similarly with your demo you've linked above, you've said 'doesn't initially apply' to all the from tweens. But quite the opposite is true, they are all immediately 'applying' by rendering at their end value. Let's break it down a bit - first step, initial positioning ✨ I think potentially the thing that's tripping you up here is referring and thinking of 0 duration tweens as 'animations' The thing is, they aren't animations. Animations imply a duration, in order to animate we have to have some values to animate between and a period of time to 'tween' between those values. What you have here with 0 duration tweens and set 'tweens' are immediate commands. Let's just take a look at the initial positioning. I've added some set tweens, some time stamps so that the starts are staggered and I've got rid of scrollTrigger for now (as that adds some different rendering behaviour which will likely confuse things further) https://codepen.io/GreenSock/pen/MWPxbEa?editors=0010 First thing to know is that all from() tweens render immediately by default. Now, an immediately rendered from tween with a zero-duration will render immediately at the end of the tween, the final state. Because it's a from tween it runs backwards, so you're 'setting' the end value. You'll never see the values in the vars object because those are the initial values. The two tweens and set calls would also render immediately if they weren't on a timeline as they have zero duration. I've added some standalone tweens so you can see this. BUT, because they're on a timeline they're set to immediateRender: false and they're waiting for the playhead to hit them in order to 'set' their position. --- If you bop immediateRender:true on all the tweens (commented out for you in the defaults) you'll see that all the tweens act the same as the from tweens, not waiting for their place on the timeline, just immediately rendering at their end state. Probably worth saying too that 0 duration from tweens are incredibly uncommon and unintuitive. From tweens essentially say 'animate from these values' which is useful. But a zero duration from tween is basically a back to front, upside down set call. ? It's inherently going to ignore everything in the vars object. It makes my head feel funny just trying to read it. So I really don't know why anyone would be using a zero duration from tween in the first place. --- It seems to me that what you're running into and trying to understand is basically immediateRender - So here's some information. it's a little tricky to wrap your head around but it should help things click into place a little. And here's a deeper dive into this behaviour by Jack If that makes sense and we're on the same page I'm happy to elaborate more about the reversing behaviour and how ScrollTriggered timelines differ from normal timeline rendering. ✨ Also, you're not the first to get baffled by this and you won't be the last! ✨ Hope this helps!
    5 points
  40. Sounds like a good use case for clamp() https://codepen.io/PointC/pen/dygQaPj/da853be09052e3296cc321b566e75353
    5 points
  41. You're looking for collision detection. There are several threads about the topic around the forum. Here are a few to get you started.
    5 points
  42. Hi, The problem is in the math you're doing for calculating the distance constant. In an ellipse you'll need both the values on the X and Y axis for that, but a triangle circumscribed in a circle it's always an Isosceles triangle, that means both sizes are equal an the angles are 45 degrees: On top of that you are overcomplicating this quite a bit IMHO. This is far simpler, cleaner, seems to work the way you intend and you don't have to worry about the user dragging on the X axis: let radius = gsap.getProperty(table, "r"); const changeCircleSize = Draggable.create(dot, { type: "y", onDragStart: function () { dragCircle[0].disable(); }, onDrag: function () { table.setAttribute("r", Math.abs(radius - this.y)); }, onDragEnd: function () { dragCircle[0].enable(); } }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/poxOpLN Hopefully this helps. Happy Tweening!
    5 points
  43. Hello there @cobragtk - welcome to the GSAP forum. You likely could use the distribute utility, but I think you can also get the effect you are after with staggers just fine - in the end it'll probably boil down to what you are more comfortable with. Especially when it comes to adding in ScrollTrigger, I guess you will have even more options for how to approach this. Depending on where exactly you want to go with this in the end, some might be easier to implement/understand and/or make more sense to use, than others. The general idea of what you tried in your pen with regard to GSAP alone, looks great already, but with the initial setup you have it does logically not work, because GSAP will tween the lines from where they started to the full scale and then back to where they started, which is exactly what is happening. Since some of them started with a bigger initial scale than others, that's where your problem originates. One of the many great things about GSAP is, that it can practically tween on any object with properties that have numeric values. [See: "Any numeric value, color, or complex string containing numbers" in the Getting Started article] Since GSAP tweens and timelines are objects too, and they have properties with numeric values, to a certain degree that also includes them. [See: "Tween the progress() and timeScale() of an animation" in this Learning Center article] Now because calculating the progress of the timeline (as is a mentionin that second article linked) from and to when/where you'd want to have things animate could become a bit tricky, instead you could e.g. tween on the time of the timeline directly. With this approach that I'm going to use in the example below, I would suggest not setting the initial scales for each of your starting elements manually, but instead let GSAP handle that for you which will get rid of that logic problem you ran into. Since I'm going to use a fromTo tween, the initial setting will probably not be neccessary, but I still wanted to mention it as it can be handy on its own. Because you have your timeline set to paused anyway, you can now set the initial time of the timeline after its creation - you know how long it takes for 1 line to completely fill up, and that is exactly the time you want to set it to, because you want the first line to appear filled initially. Careful; in my demos below I set the duration to 1 - in your example the duration is the default of 0.5 as you did not specify it. const tl = gsap.timeline({ paused: true }) tl.to('.tick-mark', {...}) tl.time(1); Now that was easy enough, but you probably also want to end the animation in a state where the last line will stay at full width, right? For that, as mentioned above, you can create a new independent tween, that tweens the time of the timeline from that initial set time to the whole timeline's duration minus that amount it takes for one line to fill up - with an ease of 'none' as we're going to add the ScrollTrigger to this tween instead of the timeline itself now, and we want the tween to be scrubbed visually in sync with the scroll-position. gsap.fromTo(tl, { time: 1 }, { time: tl.duration() - 1, // tl.duration() - duration tick-mark ease: 'none', scrollTrigger: { trigger: "#wrapper", start: `top 50%`, end: `+=70%`, scrub: true, markers: true, }, } ) This should get you where you wanted with the part of the lines scaling up and down on scroll. https://codepen.io/akapowl/pen/JjmNMyw For the headlines to become animated/highlighted too, just add another tween to the timeline, making use of the position parameter to start it at the same time as the other tween and allow them to be synced. This example uses the same values for the tween on the headlines, as are used for the tween on the lines. https://codepen.io/akapowl/pen/vYVmJjE The tricky bit here is to get the timing right. I found that this final solution works well with a decent tween on the headline opacity... https://codepen.io/akapowl/pen/XWxRVOy ... but especially with an ease of steps(1) for if you just want to toggle between different opacity-values of the headlines. https://codepen.io/akapowl/pen/LYgyzzN I'd suggest, after digesting all this, start playing around with the values and see what they do when changing them. I added a few comments in the the last two examples posted, to try and pinpoint what's important there. I hope this will help. Happy tweening!
    5 points
  44. Hi, There is no need for something like Highway or any third party library for creating page transitions in Nuxt. Nuxt uses Vue's native transition component for that: https://vuejs.org/guide/built-ins/transition.html https://nuxt.com/docs/getting-started/transitions We do have an example that uses GSAP for creating route transitions in Nuxt3: https://stackblitz.com/edit/nuxt-starter-bthjlg You can also check our Vue3 example as well: https://stackblitz.com/edit/vitejs-vite-w8wtpj Hopefully this is enough to get you started. If you have more questions let us know and remember to include a minimal demo. You can fork any of the starter templates I linked above. Happy Tweening!
    5 points
  45. i was playing around with this last night and was kind of embarrassed with what I came up with. First, this highlight function adds or removes the active class function highlight(card, isActive) { if (isActive){ card.classList.add("isActive"); } else{ card.classList.remove("isActive"); } } Then I use this "wall of callbacks" to toggle the active class as the playhead passes through "the active zone". rawSequence.fromTo(item, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, zIndex: 100, duration: 0.5, yoyo: true, repeat: 1, ease: "power1.in", immediateRender: false, id: "currentItem" }, time) .fromTo(item, { xPercent: 400 }, { xPercent: -400, duration: 1, ease: "none", immediateRender: false }, time) //start wall of callbacks .call(highlight, [item, false], time+0.44) .call(highlight, [item, true], time+0.45) // this is the active zone .call(highlight, [item, true], time+0.55) .call(highlight, [item, false], time+0.56) each card animation is one second long so at exactly a time of 0.5 is when it is full scale and opacity. with the approach above I have one second of time from 0.45 to 0.55 where the active class is applied via the highlight callback. On either side of that range I have callbacks that remove the active class. https://codepen.io/snorkltv/pen/wvYzeYr?editors=0110 I initially tried to just set the active class at 0.5 exactly. It works fine, but with the easing it seems like you're kind of waiting for the animation to finish before it gets set. feel free to activate this chunk in the demo. .call(highlight, [item, false], time+0.49) .call(highlight, [item, true], time+0.50) .call(highlight, [item, false], time+0.51) again, I'm not super confident this is the most elegant solution but figured it might help you think of ways it could work. I imagine if you knew the direction the animation was being scrubbed you could determine whether or not the the active class should be applied or removed and avoid my brute force wall of callbacks. while I'm here I'd like to applaud at @geedix for supplying an answer that certainly works quite well.
    5 points
  46. The solution for me was the following: always-auth=true //npm.greensock.com/:_authToken='replace with your Token and keep the quotes' registry=https://npm.greensock.com
    5 points
  47. @Chriis I have made an example as you need maybe it will help you https://codepen.io/akrdesign/pen/NWOGaNv?editors=0010 I have placed the SVG on the top of the image and animated it.
    5 points
  48. The problem with translating x is that t the browser the element is still in its original position, so with this you could be clicking on an element which doest appear to be not be there. What I would do is create a timeline of you animation and make it so it is repeatable, so that if the animation loops infinitely it is correct. https://codepen.io/mvaneijgen/pen/WNabNRv?editors=0011 Then add a label to the end of each card animation, so that you can tween to that label. Then I would just add the click handler to the wrapper instead of the cards them selfs and check if there is a .nextLabel() and if not set the progress to 0. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/VwEYwmG?editors=1011
    5 points
  49. Hi @S3BASTIAN welcome to the forum! Indeed it is a bit weird to wrap your head around. Normally in GSAP things work based on durations, but with ScrollTrigger that all gets thrown out the window (not really it still matters if you have multiple animations), but in ScrollTrigger the whole animation gets played over the scroll distance you've set. Now was your scroll distance not that big. You'd it set to start at the top of .hscroll and and 90% of its height, which was around 100px and in that space you move the container 3000px, which as you figured out is really fast! So what if we set the scroll distance to be also 3000px? Much slower right? https://codepen.io/mvaneijgen/pen/gOBOyar?editors=1000 But now we have weird gaps in our work, it would be better if we could pin everything in place and then move the element, so why not do that? Pin can be true, or it can be an element (see the docs for more info ScrollTrigger docs). So what if we wrap your whole page in an element called .pinMe and set that as the pin. An other option would be to wrap the .hscroll element and the footer in an element called .pinMe and have the header do scroll away and only keep the element and the footer on screen, but I'll leave that to you. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/mdzdgrV?editors=0010
    5 points
  50. When you kill() an animation, it's to make it completely dead...not to reuse it (resurrect) it and add new tweens to it. I bet you still had all the original tweens in there, and you were just adding more...and more...and more each time and trying to play a timeline that you said should be killed which is generally a bad idea. Perhaps you meant to clear() the timeline? This is exactly why we need a minimal demo. I'd want to see how you're doing this. It sounds like maybe you kept all the old tweens in the timeline and added a bunch of new ones to the end, and perhaps you restarted it so that it was playing from the beginning with the old tweens (the new ones you added later in the timeline...and maybe they got placed AFTER your infinitely-repeating stuff which means WAAAAAAAY out time-wise?) It has nothing to do with the variable itself, and it's actually FAR more common to just create a new timeline when you want to animate to new values than it is trying to empty and then re-use the same timeline instance each time. In fact, I'd say it's a mistake I see people make - thinking they're supposed to just have one big timeline for their entire project, and just keep shoving more and more and more tweens into it based on interactions. It's quite wasteful, actually, because typically the user has no intention of doing anything with the old tweens that were at the start of that timeline...so they're just keeping those around in the timeline for no reason and making the timeline longer and longer. Those old ones should be released for garbage collection, but you're not allowing that if you just keep them in the timeline forever. If you just create a new timeline and kill() the old one, that old one (and its contents) can be garbage collected and you needn't worry about them anymore. GSAP was built to be very efficient in that way. @Chromium trust me - we're trying to help. We do this every day for hours and hours. When we ask you for a minimal demo, it's because it's very important for us to understand the context of your confusion and decide how to best address any misunderstandings we identify via the code. When everything is just conceptual and abstract, it can obfuscate the real issues. I can't tell you how many times I've seen people ask questions here and they're totally confused about something and very reluctant to provide a minimal demo because in THEIR minds, the minimal demo won't help, but then when they finally provide one we instantly see why they were having the problem and it allows everyone to get on the same page. Please trust the process - we're not trying to annoy you by pestering you for a minimal demo. I totally get that you don't know why things were breaking and that's completely fine. If you just took the time to throw together a very simple CodePen that illustrated the problem...a BROKEN CodePen...I think you'd find that we'd be able to offer you far better insight that'd serve you longer-term. In my experience, questions like this almost always stem from an engineering problem with the way you may be structuring your code (as mentioned earlier, I see people coding as if they're supposed to always reuse the same timeline for everything, or maybe they think that defining a variable, passing that variable to a tween and then later changing that variable value would somehow magically make the tween animate to that new value...stuff like that is hard to identify when speaking high-level abstractions rather than just seeing what they're doing in code). Some people (not saying this is you) are reluctant to post a minimal demo because they're self-conscious about their code, assuming they'll be harshly judged for mistakes. I can assure you that won't be the case here. Others don't want to provide a minimal demo because they think it'll take too long, so they'd rather have the volunteers here spin their wheels trying to imagine what the problem might be, but it almost always ends up taking everyone a lot more time and frustration compared to if a minimal demo was created. We definitely want to help the community achieve their best potential using GSAP which is why these forums exist. I think you'll find that in general, the people who help in this community go WAY above and beyond. Most of the people who post here aren't Club GreenSock members like you (thank you! ?) and never pay us a dime, but we do our best to help them too. I'm glad to hear that your experience thus far has been so positive, and I'm sorry to hear this most recent interaction left you disappointed. As a brand, what we really try to do at GreenSock is not only deliver the best tools but value people's TRUST. We want you to feel like it's not just some library that'll be irrelevant in 2 years like most other ones. We want you to feel like we'll be there for you for the next decade+ and when you're stuck, we've got your back. It's a very unique thing in the JS world. I hope you'll offer some grace and understanding when it comes to our efforts to deliver the help you need by requesting some information that we believe would be essential for doing so.
    5 points
×
×
  • Create New...