Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...

Leaderboard

  1. ZachSaucier

    ZachSaucier

    Administrators


    • Points

      3,889

    • Content Count

      4,339


  2. OSUblake

    OSUblake

    Moderators


    • Points

      3,467

    • Content Count

      5,776


  3. GreenSock

    GreenSock

    Administrators


    • Points

      2,773

    • Content Count

      15,019


  4. PointC

    PointC

    Moderators


    • Points

      1,984

    • Content Count

      3,877



Popular Content

Showing content with the highest reputation since 07/13/2019 in all areas

  1. 14 points
    Hey fellow GreenSockers A little over five years ago, I took a chance and posted a question on the GreenSock forum. Nobody called me dumb and that was a HUGE relief! So much so that I wrote an entire GS post about it four years ago. It was a turning point for me and my JavaScript journey. Today, I’m taking another big leap in my life and launching a web animation tutorial site. My reasons for doing so are both personal and professional. This thread is a sequel to my One Year post listed above. Call it My Five Year Journey. Personal reasons My life has been full of twists, turns and milestone events over the past few years. I turned the big 50 and ask myself every day how that’s even possible. The memories of getting my first computer (TRS-80) and learning BASIC in the early 80s are so vivid that they feel like it was only a few years ago. Wasn’t it just yesterday I was programming the PET, VIC-20 and Commodore 64 in high school? Time does fly and I’m not getting any younger. I also celebrated my 30th wedding anniversary. That event itself isn’t a reason to start a new website, but the longer I’m married, the more I realize how lucky I am to have a partner and cheerleader with me when I try new things. She has been a tremendous support in this new endeavor. I wonder how I ever talked her into marrying me all those years ago and how she has put up with me for 30+ years. The other recent personal event that has shaped my decision is the one that is affecting us all right now. Seeing the effect of COVID-19 on the world and how it has robbed too many people of their lives and livelihoods has reminded me that time is precious, and you never know what’s around the corner. As they say, seize the day. Professional reasons After taking the leap and posting that first question on the forum, I was hooked on the GreenSock community. I’ve tried to help as many people as I could in my free time. I love seeing someone have that ‘ah-ha’ moment. This new site is an extension of that desire to help and teach. This will be a difficult challenge. It would be far easier to not do this. As a lifelong introvert, I’m far more comfortable in my dark office typing away on the keyboard so this definitely pushes me out of my comfort zone. It will also be a time management challenge to keep posting new content while taking care of clients and still helping on the forum. I’ll do my best. My final professional reason is that this just seems like the universe is pushing me in this direction. I loved computers and programming in my youth, but my career turned to my other loves of video production and photography. Throughout the last decade there have been many forks in the road, and it seems like every decision has led me here. My life has now come full circle. Fear and self-doubt Despite all the personal and professional reasons listed above, there has still been the nagging self-doubt. Will it be any good? Will anyone read it? Hasn’t this already been written? Maybe others don’t have that little voice in the back of their head, but mine starts yelling at me loudly when I try something big. It’s one thing to post an answer in the forum, but quite another to really put yourself out there with a whole new site. After some sleepless nights, I finally found calm from one realization. If I can help even one person with a problem, teach them something new or spark an idea, it will all be worth it. The rest of the fears don’t matter. Life is just too short to be scared or worried. The website’s focus If you know me from the GS forum, you know I love SVGs and making them move with GSAP. The website will, of course, feature a lot of SVGs and GreenSock will power everything. However, my primary focus will be real world projects. I find that I learn best when I’m building an actual project, so I’ll try to keep that as the focus. I’ll have lots of little tips and quick things too, but projects will be the main thing. Frequent visitors to the forum also know I don’t take it all too seriously and joke around a lot. You’ll be happy to know that several of the tutorials feature terrible jokes and puns at no extra charge. Thanks to the GS gang I’ve said it many times before and I’ll say it again. Thank you to Jack( @GreenSock) for creating the tools, but more importantly, thanks for fostering a terrific online community. Had I not discovered GSAP and started hanging around here, I would not know much about JavaScript and the new site would not exist. Special shout-out to @Carl too. He’s already in the trenches with training and tutorials and has encouraged me the whole way as I was getting this thing launched. All my fellow mods — thanks for the help and comradery over the years. You are all awesome! motiontricks.com Finally, without further ado, I introduce you to motiontricks.com My best to all of you. Thanks for reading. Now, let’s get those pixels movin’! 🚀 -Craig (PointC)
  2. 13 points
    A GSAP tale: One goofy guy’s odyssey from knowing nothing to knowing just enough to confuse himself. (This is crazy long so feel free to jump to the epic conclusion). Greetings fellow GreenSockers. The end of this week marks the one-year anniversary of my first post on the forum so I thought I’d take the opportunity to share my 12-month story and hopefully encourage others to jump into the conversations around here. Maybe you’ll recognize yourself in some of the things I’ve experienced. My quick history in a nutshell Web design and coding is a second career for me. After 15 years of owning and operating a photography studio and processing lab (back in the film days - yup - I’m old), the digital camera came along and changed that industry, which necessitated a new career for me. I shifted to video production, which led to motion graphics and finally to web design. Our little agency now offers all those services. The web design clients never needed anything fancy so JavaScript took a back seat to HTML & CSS only sites for a number of years. JavaScript & GSAP: false starts and other obligations I first discovered GSAP a few years ago, but only tried it briefly. It looked cool, but with the time obligations of field video work and motion graphics jobs, it wasn’t something I could work into the schedule. Besides that, it was JavaScript – too complicated I thought. I knew JavaScript was the third piece of a good web designer’s skillset along with HTML and CSS, but I always convinced myself that I didn’t have the time and the sites we built didn’t need it. JavaScript Books + Classes = Fail I did make a few attempts at reading some JavaScript books and working through some online tutorials, but it just never ‘stuck’. Maybe the examples were too theoretical and dry or they were the wrong books and classes. I really don’t know, but I abandoned the learning process a number of times. Cut and Paste mentality Why did I really need to learn anyway? You can just Google what you need, cut and paste some code and presto – you’ve got some working JavaScript or jQuery. I only understood a small portion of what I was cutting and pasting, but hey… it worked so the problem was solved. That’s how I operated for quite some time. What’s a loop? What’s an array? What’s an object? Who cares? Wait a minute. This is ridiculous. Last spring, I was remodeling our company website and I had all these grand visions about making things move and behave in certain ways. Googling for code just wasn’t cutting it. I suddenly felt stupid. “This is ridiculous!” I thought. I should be able to learn how to write my own code. Oh yeah, I remembered that GreenSock thing I had looked at a few times and abandoned. That might work. Maybe I could actually learn how to use it this time. I become a forum lurker I started lurking in the shadows of the forum. After reading a lot of posts, I saw people asking many types of questions from simple to crazy complicated (at least to me). Two things I noticed were that every effort was made to find an answer (no matter the difficulty level of the question) and not one post was condescending or snarky. That’s quite rare on the ol’ interwebs, isn’t it? Hmmmm…maybe I’m in the right place. Oh boy… time to ask a question of my own One of the great things about learning GSAP is you’ll also pick up a lot of other JavaScript and/or jQuery along the way. I kept reading and practicing with some simple tweens, but now I had a question. Dare I post? I suppose, like many others, I feared looking like an idiot even though the forum members and moderators seemed quite nice and helpful. I do several dumb things every day so you’d think I’d be used to it by now. Oh well, here goes. My first question had to do with the indexOf() a Draggable snap array. Within 30 minutes, Diaco and Rodrigo had posted great answers and neither one called me stupid! Yay – how cool. I get hooked on GSAP and the forum About that same time, I decided our company should discontinue on-site video production and switch to studio only filming. I got tired of lugging loads of video gear in and out of buildings – it’s quite tiring and as I mentioned earlier – I’m old. This freed up some time and I decided to dedicate that time to learning GSAP and maybe, one day, even helping others. It wasn’t too long and I actually knew the answer to a forum question. I posted some information and wow – a little red indicator lit up on my control panel. Someone liked something I wrote. How fun – I’m hooked. Carl makes direct contact I continued to learn and experiment. I posted a few additional questions of my own, but I tried to answer more than I asked. If someone posted a question for which I had no answer, I tried to look it up in the docs and figure it out. Most of the time I was far too slow and Jack, Carl or one of the mods would already have the answer posted before I was done reading the question, but it was an interesting way to learn. I did sneak in a few good answers, which led to a private message from Carl. He thanked me for participating and helping in the forums. I thought it was pretty cool that a super smart guy like Professor Schooff would take the time to do that for little ol’ me. My decision to dedicate time to the platform and forum was reinforced. Blake and I have a conversation I don’t recall if it was a back and forth in a forum post or a private message conversation, but Blake told me something that, of course is obvious, but it stuck with me and is important for all of us to remember. He mentioned that we all enter this learning process knowing nothing. If someone of Blake’s considerable skill level can be humble enough to remember first starting out in code, there may be hope for me after all. I guess if you think about it, there was a time when the simple concept of a variable was brand new to all of us. We’re not born with these abilities. They’re learned and we’re all at different points on the educational path. Never feel stupid for not knowing something. Moderator Promotion Throughout the last year, I’ve continued to learn and study both GSAP and JavaScript. Some of those books I abandoned in the past even make sense now. I’ve tried to be active in the GS community and answer as many forum questions as possible. If I’ve answered a question of yours, I hope you found it somewhat helpful. I’ve cranked out some fun CodePens and finally started a Twitter account to tweet them out. I am nowhere near an expert with GSAP or JavaScript, but I know so much more than I knew a year ago. Apparently I know enough to be entrusted with a forum promotion to Moderator status. I’m honored to be included on such an amazing team. 12 months down – what’s next? My agency duties are still numerous so I can’t dedicate full time to coding, but it remains something to which I’m committed and thoroughly enjoy. I started this 12-month GSAP journey just wanting the ability to write my own code rather than cutting and pasting the work of others. I’m confident I have achieved that, but I still have days when a simple piece of code just won’t coalesce in my brain and that can be frustrating. I guess we all have those days, right? I make several mistakes every day, but that’s o.k. too. I learn a lot more from my screw-ups than I ever do when it all goes right on the first try. I plan to keep learning and getting better and when I get stuck, I’ll be able to get an answer from this amazing community. I’ll continue to give back to the GS community by answering any questions that are within my abilities to do so. The super mods: Jonathan, Blake, Diaco and Rodrigo Thank you to my fellow moderators. You guys rock and have taught me so much. @Jonathan – if there is a browser bug, quirk or special fix that you are not aware of, I’ve yet to read about it. Your knowledge has helped me fix many pieces of code before they even became a problem. Plus, if I ever have a question of top/left vs. x/y, I know who I’ll ask. @Blake – if I could be half as good at coding as you, I’d be a very happy guy. Your work always teaches and inspires me. I don’t think you’re allowed to ever stop posting on the forum or we may all show up on your doorstep and ask questions. @Diaco – your code is always so concise. I deconstruct some of your pens and am astounded by how much you squeeze out of a few lines. If I made some of your pens from scratch, I’d have 20 variables, 5 loops, 12 tweens and 80 lines of code. You do the same with two variables and 4 lines of code. Amazing stuff. @Rodrigo – when searching the forum, I often land on one of your past posts and learn a lot. Your knowledge is vast and I wish you had more time to post around here. Your ninja skills are incredibly strong. Our superhero leaders @Carl – I’ve participated in several online forums ranging from graphic design to 3D to video production, but the GreenSock forum is the best and a big part of that is you. You not only provide great answers, but you do it in clever ways with just the right amount of humor thrown in here and there. The collection of videos you’ve made is invaluable and should be mandatory viewing for anyone interested in GSAP. I’ve seen you monitoring the forums at all hours of the day and even on weekends. When you get any sleep I’ll never know, but I thank you for your dedication and sharing your knowledge. @Jack – how you had the vision to start GreenSock and write the first version of the animation platform I can only imagine. I’m glad you did because GSAP is such an amazing collection of tools. The friendliness of the community is definitely following your lead. I don’t understand a lot of what you talk about sometimes, but I know enough to be amazed by your brilliance and talent. You call yourself just a guy who geeks out about code, but you’re more than that. You’re a smart and generous innovator who’s created a special brand and place on the web. I think I can safely speak for the community when I say we all appreciate the time and effort you put into helping us make beautiful and high-performance animations. Thank you sir. The epic conclusion. Well… maybe just a regular conclusion. If you didn’t read the whole post, I don’t blame you. It’s ridiculously long and I’m just some guy you don’t know so I’ll wrap it up with this bit of advice. Whether you’re a genius or feel like an idiot, it doesn’t matter. Try to learn one new thing each day and before you know it, a year will have passed and all those little bits will add up to new skills and abilities. If you’ve never posted on the forum, please jump in and participate. The more voices we have around here, the more we all benefit. If you need an answer, please don’t be afraid to ask a question. Believe me, I’m just some goofy guy in front of a computer. If I can learn this stuff, so can you. As I begin my second year in GreenSockLand, I’m looking forward to learning more, seeing everyone’s work and answering as many of your questions as I can. This is an amazing community and I encourage anyone reading this to set up an account and get involved. My best to all of my fellow GreenSockers. See you around the forums. Edit and Update (July 2020): I just made it to five years of hanging around the forum and you can read the continuation of my journey here. - Craig (PointC) PS I made a little CodePen to commemorate my one-year forum anniversary. It’s how I felt before and after discovering the power of GSAP. Enjoy.
  3. 13 points
    Are you familiar with CodePen Challenges? In June 2020, GreenSock got to host it! We decided that it'd be fun to have a competition and give away 3 "Shockingly Green" Club GreenSock memberships each week! What is a CodePen Challenge? CodePen is a site where you can create and share small frontend web projects that you've made. You can also start with another person's creation and then modify it to become your own creation (this is called forking). Every month, CodePen hosts 4 weekly challenges with different themes. They host these challenges to help you improve your frontend skills, express yourself, and have some fun! How did this competition work? Every Monday this month, check the CodePen Challenges page for the new theme (you can sign up there for notifications too). Then make something based on that theme! It could be anything. Each week we will provide some different ideas to get you started, but you can create anything so long as it fits the challenge prompt that week. To submit entries to the competition, people tagged @GreenSock on Twitter along with a link to your pen. At the end of the each week, our panel of judges went through and pick their favorite pens that were created that week. The creators of the top 3 pens each week received a one-year "Shockingly Green" Club GreenSock membership on us! Who were the judges? Meet our lovely judges for the GSAP CodePen Challenge Competition (you should follow them!): Aaron Iker Adam Kuhn Annie Liew Cassie Evans Chris Gannon Craig Roblewsky Jhey Tompkins Lisi Linhart Louis Hoebregts Lynn Fisher Olivia Ng Pete Barr Shaun Gorneau Steve Gardner Tom Miller Una Kravets What's this week's challenge? Unfortunately the CodePen Challenge competition is over. But you're free to follow the same challenge prompts to inspire you to create something! We'd still love to see it. You can view all of the challenge prompts on CodePen. The winners Week 1: Sequencing Congratulations to our week one (sequencing) winners: Benoît Wimart, Sicontis, and Cristobal Garcia! Be sure to check out the rest of the submissions. modulofont Sequencing (Mom’s Diner) .cCmsCategoryFeaturedEntry .cBlackContent a { text-decoration: none; } html[dir="ltr"] .ipsGrid_span4:nth-child( 3n+1 ) { margin-left: 2.127659574468085%; } Taika cruising through La Gran Sabana Week 2: Bubbling Congratulations to our week two (bubbling) winners: Louise Flanagan, Oscar Salazar, and Wendy Kong! We had to bring in an extra judge to break ties because the voting was so close so be sure to view all of the submissions as well. Bubbly Bath Bubbles Bunny Breathing Exercise Week 3: Sliding Congratulations to our week three (sliding) winners: Oscar Salazar, Wendy Kong (both are winners two weeks in a row! Very impressive.), and ycw! You can view all of the submissions here. Slash GSAP Penguin Blue Room Week 4: Scrolling Congratulations to our week four (scrolling) winners: supamike, Ismael Martínez, and Shunya! View all of the submissions here. 3D Banners Personal Page Underwater Scrolling Animation Thanks so much to all who participated. We couldn't have ran this competition without you!
  4. 9 points
    Wow! I just noticed the GSAP forum cracked 10,000 topics. I just wanted to take a moment to thank Jack for not only creating a fantastic set of animation tools, but also for fostering such a great community. I’ve said it before, and I’ll say it again — this forum really is an oasis in the snarky Interwebs desert. A friendly community with loads of great people and tons of info and demos. Truly one of a kind. A message for any lurkers — try jumping in and asking (or answering) a question. I think you’ll be glad you did. Congratulations Jack. Looking forward to GSAP 3.0 and the next 10,000 topics.
  5. 8 points
    By encourage I think he meant "incessantly bugged me for 2 years" Now, that Craig got his blog up, I'll move on to @OSUblake The world needs a GSAP + Pixi hero. Great job, Craig. I'm truly impressed. I can't wait to finish reading all of it. I'm sure motiontricks.com will be a tremendous resource for anyone learning and mastering GSAP. I'll whole-heartedly recommend it. When's the next post going live?
  6. 8 points
    @ddi-web-team @Sygol @Yannis Yannakopoulos I whipped together a helper function that should make this quite easy. Check it out in this CodePen: https://codepen.io/GreenSock/pen/823312ec3785be7b25315ec2efd517d8?editors=0010 We may end up adding it as a static method on ScrollTrigger if there's enough interest. What do you think?
  7. 8 points
    I’ve talked about this in other threads, but I think it’s worth making a standalone tip for it so here we go. There are three things that will eliminate coordinate surprises and weird transforms with your SVG exports. A background rectangle A background rectangle A background rectangle Yes, it’s that important. Take this simple 600 x 200 SVG. Nothing but a circle, rectangle and a blobby path. Here’s how it looks in Adobe Illustrator. You’ll see that I also have a background layer with a 600 x 200 white rectangle in it. Exporting that SVG produces this result: <svg xmlns="http://www.w3.org/2000/svg" width="600" height="200" viewBox="0 0 600 200"> <g id="Background"> <rect width="600" height="200" fill="#fff" /> </g> <g id="Children"> <circle cx="100" cy="100" r="75" fill="#75131a" /> <rect x="225" y="25" width="150" height="150" fill="#136036" /> <path d="M575,100c21,5-33.58,90-75,90s-104-82-75-90c39.93-11,33.58-88,75-88S534.71,90.41,575,100Z" fill="#0071bc" /> </g> </svg> Exactly as I’d like. A 600 x 200 viewBox and everything is positioned where I expected it. Now, what if I didn’t use the background rectangle? Here’s the export result after removing it: <svg xmlns="http://www.w3.org/2000/svg" width="554.65" height="178" viewBox="0 0 554.65 178"> <circle cx="75" cy="88" r="75" fill="#75131a" /> <rect x="200" y="13" width="150" height="150" fill="#136036" /> <path d="M575,100c21,5-33.58,90-75,90s-104-82-75-90c39.93-11,33.58-88,75-88S534.71,90.41,575,100Z" transform="translate(-25 -12)" fill="#0071bc" /> </svg> You can see the viewBox has now changed to 554.65 x 178 instead of my artboard size of 600 x 200. The circle and the rectangle no longer have the coordinates I expected, and the blobby path has some weird transform applied to it. This is only three simple elements and it’s a bit difficult to animate with precision. Now think about complex SVGs with multiple paths and how this could cause problems with your animations. Bottom line: use a background rectangle the same size as your SVG, export your code and then delete the rectangle if you don’t need it. Hopefully this info helps with your SVG projects. Happy tweening.
  8. 8 points
    Hi @Saurabh Nandwana That's quite an ambitious task! Performant vector rendering is a problem that people have been working on for years. Have you checked out bodymovin/lottie? It's a vector player, but it's not a perfect solution, nor is it always performant. https://github.com/airbnb/lottie-web https://codepen.io/collection/nVYWZR There's even a nice web component for it so you can use it just like a <video> element. https://codepen.io/fernandocomet/pen/JLrbYB Having too many canvas layers can slow stuff down. I remember the developer of bodymovin/lottie saying that it uses a dirty rectangle algorithm to limit redrawing to parts of the screen that have changed instead of the entire scene. In general, I would say Canvas2D is probably the fastest way to render vector graphics on the web, but it does have limits. Uncheck the Use Bitmap checkbox, and you should see the performance drop as it switches to vector rendering. https://codepen.io/osublake/pen/a7868b452dfb5eebad6ee9ae24c2bfc3 Morphing works well for some stuff, but it's probably not the best tool for a Simpsons cartoon as its hard to control the movement like you can with joints and bones. WebGL is still a nice option for 2d, but it won't automatically fallback to canvas as WebGL uses a completely different API. However, WebGL support is very good. I'm pretty sure it will fallback to WebGL 1, but PixiJS was never really designed to really handle complex vector graphics. It's optimized for raster graphics. For SVG, it converts them into bitmaps, so they are static. To change a path, you would need to modify the source SVG and then get Pixi to reload it, which is a slow process. For stuff like that, it's usually faster use a Canvas2D as a texture as it's much faster to update.
  9. 8 points
    Hey Michael and welcome to the forums! Good work on your site. That is an interesting issue. I noticed that you used different selectors in the dev and production build. I also noticed that you seemed to be animating the .ys-shortcut class in production and that class is applied to both the li and the a of each of those items (and both the li and the a were being animated). So I used my dev tools to remove the .ys-shortcut class from the a and it seems to be working without the increased delay. So I'd recommend removing that class from the anchor and using some other method (like .ys-shortcut > a) to color the anchor text. Happy tweening.
  10. 8 points
    Sorry if it came off that way. I brought up CSS grid because animating tables can be very problematic. Tables were not designed with animations in mind, which is why you still have to use attributes to get some table elements to display correctly. And there is usually more than one way to solve a problem. Using CSS grid was part 1 of my recommendation. You called me a troll before I got to part 2 below. The gaps are caused because of rounding. An 81px wide element at a scale of 0.786 is 63.666000000000004 pixels. Not exactly a whole number, so you might see artifacts bleeding through. To get rid of those gaps, you can use will-change: transform; in your css. The browser can rasterize (take a snapshot) of the layout before scaling gets involved. https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
  11. 7 points
    With over 100,000 posts in the popular GreenSock forums, we've noticed some common mistakes that you'd be wise to avoid. We threw in a few tips as well. Here is a summary of the mistakes: Creating from() logic issues Not setting ALL transforms with GSAP Not using xPercent and yPercent Recreating animations over and over Adding tweens to completed timelines Not using loops Importing things incorrectly Using the old/verbose syntax Creating from() logic issues It's usually smart to use .to() and .from() tweens instead of .fromTo() because they're more dynamic - they pull either the starting or ending values from whatever they happen to CURRENTLY be at the time that tween renders for the first time. It’s one of the tips in the article on animating efficiently. But be careful because that dynamic nature can bite you in a few scenarios. First, keep in mind that .from() tweens go from the provided value to the current value. Take a look at this example: See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. Try clicking it one time and letting it play. It works, fading in the element. Now try clicking it multiple times right after each other. The box stops showing up because it uses the current opacity as the end point which, if the animation has not completed, is some value less than 1. The fix for this is simple: use a .fromTo(). Alternatively you could create the animation beforehand and use a control method (we'll talk more about this approach later in this article). See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. Second, keep in mind that by default immediateRender is true by default for .from() and .fromTo() tweens because that's typically the most intuitive behavior (if you're animating from a certain value, it should start there right away). But if you create a .from() tween after a .to() tween affecting the same properties of the same object, try to figure out what will happen: const tl = gsap.timeline() tl.to(".box", {x: 100}); tl.from(".box", {x: 100}); You might expect the box to animate x from 0 to 100 and then back to 0. Or maybe you'd expect it to animate from 0 to 100 and then stay at 100. Let’s see what happens: See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. The box animates x from 100 to 100 and then back to 0. Why is that? By default .to() tweens wait to render until their playhead actually moves (it's a waste of CPU cycles to render at a time of 0 because nothing will have changed). But since from() has immediateRender: true, x jumps to 100 immediately on the current tick! Then it runs the .to() tween on the next tick (since it’s first in the timeline) and records the current starting value which is 100! So it animates 100 to 100 over 0.5 seconds. Then it runs the .from() tween which has the cached value of 0 as the end value. If you have several timelines affecting the same element, situations like this can be a little tricky to catch. So just be mindful of how things work when using .to() and .from() tweens. They’re very powerful but with power comes responsibility. A simple solution here is to set immediateRender: true on the .to() tween, or immediateRender: false on the .from() tween. The third situation is similar but involves repeatRefresh and repeats. Let’s say you have a situation where you want a looped animation that fades in some text and fades it out. You could create a timeline, use a .from() to fade in the text, then use a .to() to fade it out: const tl = gsap.timeline({repeat:-1}); tl.set(".text", { color: "random([green, gray, orange, pink])" }, 2); tl.from(chars, { opacity: 0 }); tl.to(chars, { opacity: 0 }); This will work just fine! Here’s the same thing but staggered using SplitText to make it look a little nicer: See the Pen Fade in and out text by GreenSock (@GreenSock) on CodePen. But this only randomizes the colors at the start. What if we want new random values each repeat? That’s where repeatRefresh comes in. Let’s add repeatRefresh: true to see what happens: See the Pen Random on Reset (wrong way) by GreenSock (@GreenSock) on CodePen. The animation plays correctly the first time but after that the elements don’t fade in a second time! Why is that? repeatRefresh uses the end values of the animation as the starting values of the next iteration. In this case, the opacity of our text elements are all 0 at the end. So when the animation gets to the .from() the second time around, the opacity animates from a value of 0 to a value of 0 since the tween is relative. What we want to do instead is always animate from a value of 0 to a value of 1 so here the easiest fix is to use a .fromTo(): See the Pen Random on Reset by GreenSock (@GreenSock) on CodePen. Now it does what we want. There are other solutions like using a .set() before the .from() but most often it’s easiest to just use a .fromTo() in cases like this. Not setting ALL transforms with GSAP If you are going to animate an element with GSAP, even the initial transform values (including on SVG elements) should be set with GSAP because it delivers better: Accuracy - The browser always reports computed values in pixels, thus it's impossible for GSAP to discern when you use another unit like % or vw in your CSS rule. Also, computed values are in matrix() or matrix3d() which are inherently ambiguous when it comes to rotation and scale. The matrix for 0, 360, and 720 degrees are identical. A scaleX of -1 results in the same matrix as something with rotation of 180 degrees and scaleY of -1. There are infinite combinations that are identical, but when you set transform-related values with GSAP, everything is saved in a perfectly accurate way. Performance - GSAP caches transform-related values to make things super fast. Parsing all of the components from a computed value is more expensive. If you are worried about a flash of unstyled content, you can handle that by using a technique that hides the element initially and then shows it via JavaScript as this post covers. Or you can set the initial styles with CSS rules and ALSO set them in GSAP. Not using xPercent and yPercent Did you know that you can combine percentage-based translation and other units? This is super useful if, for example, you'd like to align the center of an element with a particular offset, like {xPercent: -50, yPercent: -50, x: 100, y: 300}. We often see people use percent values in the x and y properties which is technically possible but can cause confusion at times. For example, if you set x and y to "-50%" and then later you set xPercent: -50, you'd see it move as if it's at xPercent: -100 because the x and xPercent both have -50%. Whenever you're setting a percentage-based translation, it's typically best to use the xPercent and yPercent properties. // Not recommended x: "50%", y: "50%", // Recommended xPercent: 50, yPercent: 50 Recreating animations over and over Creating your tweens and timelines beforehand has several advantages: Performance - Instead of having to create them right as they’re needed, you can do it ahead of time. Additionally, you need fewer instances of animations. Most of the time you’d never notice, but it’s good practice. Simplified logic - This is especially true when related to user interaction events. Freedom - Want to pause an animation when an event happens? Do it. Want to reverse an animation when the user does something? No problem. This sort of thing is much more difficult to handle when you create animations inside of event callbacks. Most of the time when you create animations beforehand, you will want to keep them paused until they’re needed. Then you can use control methods like .play(), .pause(), .reverse(), .progress(), .seek(), .restart(), and .timeScale() to affect their play state. Here’s a simple example: See the Pen Playing and reversing an animation on hover by GreenSock (@GreenSock) on CodePen. For more information related to creating animations beforehand, you can see the animating efficiently article. One exception to this rule is when you need things to be dynamic, like if the initial values may vary. For example, if you’re animating the height of the bars in a chart between various states and the user may click different buttons quickly, it’d make sense to create the animation each time to ensure they flow from whatever the current state is (even if it's mid-tween) like the demo below. See the Pen Playing and reversing an animation on hover by GreenSock (@GreenSock) on CodePen. Adding tweens to completed timelines A common pattern of mistakes that I’ve seen goes like this: const tl = gsap.timeline() tl.to(myElem, { x: 100 }); myElem.addEventListener("click", () => tl.to(myElem, { x: 300 }) ); Did you catch the mistake? If you add new tweens to a timeline that is already completed, they won’t be called unless you re-run the timeline. Almost always in these situations you should just use control methods for a previously created animation or create a new animation instead (not using an existing timeline) following the guidelines that we covered in the previous section. Not using loops If you want to apply the same effect to multiple elements (sections, cards, buttons, etc.) when a certain event happens to each one, you should almost always use a loop. For example, don’t use a selector like "button" when you want it to affect just one button. For example, if you wanted to fire an effect when each button is clicked: // BAD: immediately animates ALL buttons at once! gsap.effects.explode("button", { direction: "up", duration: 3 }); // GOOD: animation is specific to each button, and only when clicked gsap.utils.toArray("button").forEach(btn => btn.addEventListener("click", () => gsap.effects.explode(btn, { direction: "up", duration: 3 })) }); Inside of this loop, you can use a selector that is scoped to the given element so that you're only getting things INSIDE that element. For example: gsap.utils.toArray(".container").forEach(container => { let info = container.querySelector(".information"), silhouette = container.querySelector(".silhouette .cover"), tl = gsap.timeline({ paused: true }); tl.to(info, { yPercent: 0 }) .to(silhouette, { opacity: 0 }, 0); container.addEventListener("mouseenter", () => tl.play() ); container.addEventListener("mouseleave", () => tl.reverse() ); }); See the Pen Who&#39;s That Pok&eacute;mon? - forEach example demo by GreenSock (@GreenSock) on CodePen. Importing GSAP incorrectly A common issue people face when using GSAP in a module environment is importing GSAP or its plugins incorrectly. Most of the time import errors error can be avoided by thoroughly reading the relevant parts of the installation page. I won't copy all of the details into this post, but be sure to make use of that page if you're facing any sort of import error. It even has a very handy GSAP install helper tool that can generate the correct import code to use in most environments. Using the old/verbose syntax Drop the Lite/Max I regularly see people using the old syntax even though they are loading GSAP 3. Old habits die hard. Even though the old syntax still technically works, the new modern GSAP 3 syntax is sleeker and simpler. Plus the old syntax won't be supported in GSAP 4 (which is far off in the future, but it's still a good idea to write future-friendly code). For example instead of using something that has Lite/Max in it, just use gsap: // old TweenLite.to() TweenMax.from() new TimelineMax() // new gsap.to() gsap.from() gsap.timeline() Use the string form for eases The shorter string form of eases requires less typing and lets you avoid extra import statements in module environments. // old Power2.easeOut Sine.easeInOut // new "power2" // The default is .out "sine.inOut" Duration belongs in the vars parameter Putting the duration inside of the vars parameter does require a bit more typing, but it makes things more readable and intuitive. GSAP’s defaults and effects are very helpful but you can’t make use of them if you’re putting the duration as the second parameter. // old gsap.to(elem, 1, { x: 100 }); // new gsap.to(elem, { duration: 1, x: 100}); // using GSAP’s defaults: const tl = gsap.timeline({ defaults: { duration: 1 } }); tl.to(elem, { x: 100 }); // no duration necessary! tl.to(elem, { y: 100, duration: 3 }); // easily overwrite the default value For a more full listing of changes in GSAP 3, check out the GSAP 3 Migration Guide. Numerical values don’t usually need to be strings For example if you want to set the x transform to 100 pixels, you don’t need to say x: "100px", you can just say x: 100. Simple! The only time when you need to pass numerical values as strings are if you need to change the unit (like x: "10vw") or pass in a complex value (like transformOrigin: "0px 50px"). The target of a tween can be a selector string I often see people do something like this: gsap.to(document.querySelectorAll(".box"), { x: 100 }); Or even with jQuery: gsap.to($(".box"), { x: 100 }); Both of the above will work but could be simplified by passing a selector string in as the target; GSAP will automatically use .querySelectorAll() to get a list of all of the elements that match. So the above can be written simple as gsap.to(".box", { x: 100 }); You could also pass in a complex selector string like ".box, .card" and it will select all boxes and cards. Or use an Array of elements so long as they are of the same type (selector string, variable reference, generic object, etc.). Conclusion So how'd you do? Is your GSAP code clear of these common mistakes? Hopefully you learned a few things. As always, if you need any help, the GreenSock forums are a fantastic resource. We love to help people develop their animation superpowers. If you're looking for another great learning resource, read how to animate efficiently! Now go forth and tween responsibly!
  12. 7 points
    Scroll-driven animations re-invented Animate anything on scroll DOM, CSS, SVG, WebGL, Canvas, whatever. Toggle playback state or scrub through animations Entering or leaving a ScrollTrigger area can make an animation play, pause, resume, reverse, restart, or complete...or you can make the scrollbar can act like a scrubber! Pin elements in place Make an element appear immune to scroll changes while the ScrollTrigger is active. This is surprisingly useful for creating slick effects and keeping your animation in view during the scroll. Insane levels of flexibility ScrollTrigger is a control freak's dream when it comes to choreographing animations, but its rich callback system also lets you accomplish things totally unrelated to animation. Directionally smart ScrollTrigger supports vertical and horizontal scrolling, and lets you check if the last scroll movement was forward or backward, and even tracks velocity! Automatic resizing ScrollTrigger elegantly adjusts to viewport size changes. You can even use function-based start/end values to run custom logic or tap into fancy responsive CSS changes. Maximum performance ScrollTrigger uses all kinds of techniques to maximize performance like throttling updates, pre-calculating intersection points to minimize effort during scroll, leveraging transforms, layerizing elements to utilize the GPU, etc. Integrated with GSAP ScrollTrigger is built on GSAP, the battle-tested standard for JavaScript animation that's used on over 10,000,000 sites worldwide including most award-winning ones. Get started with ScrollTrigger Download Documentation Examples Featured ScrollTrigger demos View all demos
  13. 7 points
    Hi @Juc1, The way I usually handle something like this is by cloning the first slide, appending it to the end, and allowing it to become the final tween before restarting the timeline. This gives a nice, seamless affect of an infinite stack. In my case, I'm using jQuery clone and appendTo to take care of this (because it makes it dead simple). The other thing is, I reordered the SVG <g> elements to be one, two, three (rather than three, two, one) to take advantage of the default stacking order. https://codepen.io/sgorneau/pen/gOPOeeY?editors=0010 Happy tweening! Shaun Edit: Also note that since you are using the same properties and values on each tween ... you can stuff those into the timeline's defaults and not have to worry about assigning them to the individual tween's
  14. 7 points
    First, an animation/timeline/tween is not a state. Use a ref instead. A ref is just like using this in a class component. When you set state in hooks, you lose everything that wasn't saved in a ref/state. https://codesandbox.io/s/gsap-and-usestate-4prg6?file=/src/child1.js I think that is really confusing, which is why I prefer using classes for gsap animations.
  15. 7 points
    You can skew elements based on the scroll velocity using the InertiaPlugin or ScrollTrigger: With the InertiaPlugin With ScrollTrigger
  16. 7 points
    Hey @agilepixel and welcome to the GreenSock forums! Thanks for being a Club GreenSock member. We couldn't do what we do without people like you. GreenSock is actually working on our own scroll plugin but it hasn't been released yet. Until we have the scroll plugin, to animate thing on scroll you have to use either the scroll position or the intersection observer API. Here's a basic demo using the scroll position: https://codepen.io/GreenSock/pen/BaNPoEK And here's an article that talks about using the intersection observer API with GSAP: https://medium.com/elegant-seagulls/parallax-and-scroll-triggered-animations-with-the-intersection-observer-api-and-gsap3-53b58c80b2fa
  17. 7 points
    Hey @Robert May, this example could be helpful - its still gsap 2.0 https://codepen.io/mikeK/pen/ZwmdYv Happy tweening ... Mikel
  18. 7 points
    Hey, A prehistoric animation, no-scroll https://codepen.io/mikeK/pen/BaNPLNL Stay healthy ... Mikel
  19. 7 points
    Hi @invisibled, The duration of your tween won't make any difference here, as you are advancing the total progress of the tween from 0 to 1, so your duration number could be 0.2 or 100 and the result would be basically identical. I generally just set my duration to 1, so it matches progress in this situation. You'll also want to pause your timeline when you set it as well. Your math to get your duration math should be similar to this: // Get scroll distance to bottom of viewport. const scrollPosition = (window.scrollY + window.innerHeight); // Get element's position relative to bottom of viewport. const elPosition = (scrollPosition - el.offsetTop); // Set desired duration distance. const durationDistance = (window.innerHeight); // Calculate tween progresss (100vh). const currentProgress = (elPosition / durationDistance); I'd also recommend making the jump to GSAP3, if you can. You may also find this article helpful, as it covers similar progress math and a few other approaches to scroll-tied animations with GSAP (the bottom example of this article uses the scroll event listener): https://medium.com/elegant-seagulls/parallax-and-scroll-triggered-animations-with-the-intersection-observer-api-and-gsap3-53b58c80b2fa
  20. 7 points
    Yes, but why? Can you justify the need for React? No, seriously. A lot of devs think React is necessary for some reason, but my response to using React for a project is usually... (insert nationality) If you're new to JavaScript, then I would focus on the language itself, DOM APIs, and CSS. Those amazing sites you see aren't amazing because they use React. They're amazing because they use gsap and three.js. 😉
  21. 7 points
    Hey @alexandrosb, If you position all elements in one SVG - including the paths for the animation - you will definitely make it easier for yourself. https://codepen.io/mikeK/pen/WNvoyor Good Appetite ... Mikel
  22. 7 points
    It works in all modern browsers. https://caniuse.com/#feat=intersectionobserver For those who think supporting IE is a good idea, there are polyfills. https://github.com/w3c/IntersectionObserver Well this is a gsap forum, so I'm of course including gsap as a library. But you don't need any scrolling libraries when using the intersection observer. That kind of defeats the whole purpose.
  23. 7 points
    Eases are just functions now. var easedValue = Power2.easeIn( value ); Note that you can use use gsap.parseEase() to get the ease function from a string. var power2In = gsap.parseEase("power2.in"); var easedValue = power2In( value );
  24. 7 points
    Ok, here's a simple demo. If you can get a good looking path animation, then placing baubles shouldn't be too hard. You can use cubic beziers if needed, it just uses a different calculation. https://codepen.io/osublake/pen/7b238a209825cd951d768f41715b8fd7
  25. 7 points
    At its core, GSAP doesn't do DOM manipulation. That's what the CSSPlugin does, so yes, you can use the easing functions for whatever you want. Every ease has a .getRatio() method, where you pass in a normalized value from 0 to 1. var ratio = Power1.easeIn.getRatio(0.5); Check out this post where I use different easings to plot points for sine waves. If you need help normalizing a value, here's a little helper function. Just pass in the current, min, and max values. // normalize will return a value between 0 and 1 function normalize(value, min, max) { return (value - min) / (max - min); }
  26. 7 points
    Might want to check someone’s history, skill set, and experience before you accuse them of trolling.
  27. 7 points
    Welcome to the forum. You can check out the Bezier plugin: https://greensock.com/docs/Plugins/BezierPlugin The MorphSVG plugin has a .pathDataToBezier() method. https://greensock.com/docs/Plugins/MorphSVGPlugin You may also be able to make it work with a textPath animation. I wrote about that here: Demo from that thread: https://codepen.io/PointC/pen/vRzmeO Hopefully that points you in the right direction. Happy tweening.
  28. 6 points
    Hi Johnny, That banner is part of my premium GreenSock tutorials at: https://www.creativecodingclub.com/bundles/creative-coding-club Here is the codepen demo if you want to use it: https://codepen.io/snorkltv/pen/BaoZKJN Instructions on how it works and how it was made are available in GSAP 3 Beyond the Basics
  29. 6 points
    I think we may be able to offer some hooks into ScrollTrigger that'd make this kind of thing possible. I've added an experimental feature into the latest beta that'd let you do this: // Tell ScrollTrigger to use these proxy getter/setter methods for the "body" element: ScrollTrigger.scrollerProxy("body", { scrollTop(value) { if (arguments.length) { bodyScrollBar.scrollTop = value; // setter } return bodyScrollBar.scrollTop; // getter }, scrollLeft(value) { if (arguments.length) { bodyScrollBar.scrollLeft = value; // setter } return bodyScrollBar.scrollLeft; // getter } }); // when your smooth scroller updates, tell ScrollTrigger to update() too. bodyScrollBar.addListener(() => { ScrollTrigger.update(); }); When I dropped that into your demo it seemed to work okay but I very well may be missing something: https://codepen.io/GreenSock/pen/1e42c7a73bfa409d2cf1e184e7a4248d?editors=0010 Basically you're saying "Hey ScrollTrigger, whenever you want to get or set the scrollTop/scrollLeft on this element (body), use these methods instead" and then you do whatever you want inside those methods. The preview of the next release is at https://assets.codepen.io/16327/ScrollTrigger.min.js Does that help? I welcome feedback about the API. And I'm not promising this will be in the next release but it seems likely if this works well for you.
  30. 6 points
    First, gsap has built in random support. https://greensock.com/docs/v3/GSAP/UtilityMethods/random() Use delayedCall instead of setTimeout. setTimeout is not synced with gsap. https://greensock.com/docs/v3/GSAP/gsap.delayedCall() Subtracting and adding 0 makes no sense. var x = Math.random() * (maxOffsetX - 0) + 0; // Better var x = Math.random() * maxOffsetX; .toFixed() creates a string. Bad for math. var sTo = (Math.random() * (scaleTo - 1.00) + 1.00).toFixed(2); Easy random sign. function randomSign() { return Math.random() < 0.5 ? 1 : -1; } ... gsap.to($el, { scale: sTo, x: x * randomSign(), y: y * randomSign(), duration: animTime, ease: "power1.inOut", onComplete: start }); I don't know if this fixes your issues, but it's a start. You should also wait for the image to load before storing its width and height. https://codepen.io/osublake/pen/17cbaea5c2ba927d860d74bf6540a042
  31. 6 points
    I'm so sorry about that - it was just a typo in the docs. It's "className", not "class". toggleClass: {targets: ".c, .a", className: "active"}
  32. 6 points
    Hi Bannerguy, Based solely on the information provided, the simplest approach to this would be a single tween using repeat, repeatDelay, and yoyo: https://codepen.io/snorkltv/pen/PoPZWJz?editors=0010 If you need something different please elaborate. If you find yourself struggling with the basics, I think you would really get a ton of value from my courses (see links below).
  33. 6 points
    @chrisgannon did a nice one (as you describe inside a circle). https://codepen.io/chrisgannon/pen/xqwgPq
  34. 6 points
    Hey @Chronic, Welcome to the GreenSock Forum. You don't need ScrollMagic - just a little parallax logic and everything runs smoothly. And you could use the super GSAP tool motionPath to position objects. https://codepen.io/mikeK/pen/XWbwmZY Happy tweening ... Mikel
  35. 6 points
    Mhhh... I'm not sure if I follow what you're trying to do, but it could be a eased stop to 0 degrees? I remember a sample from @Carl about easing the timescale so partial credit to him, hopefully this is close to what you want to do: https://codepen.io/rhernando/pen/zYGeXEB The idea is to tween the animation instance's timescale to make it faster/slower and then in the stop button use the directional rotation feature of the CSS Plugin to rotate the to the shortest end angle. Now this only scratches the surface of this, since you still need to calculate, according to the current speed, angle and final angle, the time for the stop animation, that should be shorter or longer depending on those factors. Right now it stops the animation using a single time value which can look odd in some cases. Hopefully this is what you're looking for and helps you get started. Happy Tweening!!!
  36. 6 points
    In fact using an useEffect or the corresponding componentDidMount in class components is the best way to be sure that the DOM elements do exist. Keep in mind though, that using that call inside an useEffect hook, will trigger that code every time the state or props of that component are updated, that's why is better to use an empty array as a second argument in the useEffect hook: useEffect(()=>{ // code in here }, []); // empty array ensures that the code is ran only when the component is mounted Also you don't need the useCallback hook to set the DOM elements. In fact I wouldn't recommend it, plus you're not using the hook correctly. The idea of that hook is to create and update values only when the dependencies in the array are updated. Right now you're passing an empty array. Also the constant you're creating is not being used anywhere in your code: // This constant is never used const el = useCallback(node => { if (!node) return; const myTitle = node.children[0]; const mySubtitle = node.children[1]; const myParagraph = node.children[2]; setState(state => [myTitle, mySubtitle, myParagraph]); }, []); Is better to create a unique variable for the parent node element. This code achieves the same result you're getting now: import React, { useEffect} from "react"; import { gsap } from "gsap"; import "./styles.css"; export default function App() { let parentNode = null; useEffect(() => { console.log(parentNode); gsap.set(parentNode.children, { autoAlpha: 0 }); const tl = new gsap.timeline(); tl.to(parentNode.children[0], { autoAlpha: 1, duration: 1 }); tl.to(parentNode.children[1], { autoAlpha: 1, duration: 1 }); tl.to(parentNode.children[2], { autoAlpha: 1, duration: 1 }); }, []); return ( <div className="App" ref={el => (parentNode = el)}> <h1>My Title</h1> <h2>My Subtitle</h2> <p>My paragraph</p> </div> ); } Happy Tweening!!!
  37. 6 points
    Credit to who? That's a fork of one of mine. Just giving you a hard time. Welcome to the forum. Just another little nugget of info for you — you can also use a clip-path for this type of reveal. Masks can also use strokes and gradients so you can get all fancy with them. Here's a little example for you. https://codepen.io/PointC/pen/VwLVxwx Hopefully that helps. Happy tweening.
  38. 6 points
    Hi @supamike, Your code looks good to me. Only thing I see is that you're passing direction into your function and not using it—not a big deal, just noticing. Also, if you're interested, this is pretty easy to do without the waypoints library, using intersection observer api: https://medium.com/elegant-seagulls/parallax-and-scroll-triggered-animations-with-the-intersection-observer-api-and-gsap3-53b58c80b2fa
  39. 6 points
    Here is a similar one to the above which may also assist you, using click instead of scroll. https://codepen.io/osublake/pen/df06754f4736f45005fe693f3113049b It was discussed in the following thread (also a mouse wheel one). Below are a few other related pens which you might also find useful to look through. https://codepen.io/sdras/pen/dXoLEJ https://codepen.io/PointC/pen/OMabPa https://codepen.io/osublake/pen/oGoyYb ¯\_(ツ)_/¯
  40. 6 points
    You should probably read through their docs. It says there are events, which you should be able to use to control gsap animations. https://github.com/locomotivemtl/locomotive-scroll
  41. 6 points
    I've been updating my slider demos to GSAP 3 and noticed a difference in endX and a snap array. In GSAP 2 the endX would always be accurate, but in GSAP 3 I'm getting numbers that aren't in the array. At first I thought it was a rounding error, but depending on how you throw the target, you can get some wildly different numbers. Am I doing something wrong here or has something changed when I was on hiatus? Here are comparisons of 2 and 3. https://codepen.io/PointC/pen/ExjRaJV
  42. 6 points
    First, this is using the new GSAP3 syntax, which won't work with version 2.x (which appears to be what you're importing). As @GreenSock said, the Getting Started page is super helpful. But if you're super new to HTML and CSS, learning JS is going to be pretty overwhelming on top of that. It's important, from a learning and understanding standpoint, to have a good knowledge of the basics of HTML and CSS down before you dive into learning (JS and) GSAP. That said, to get started, you're HTML file should look similar to this: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <!-- custom css --> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body> <!-- stuff on your website --> <img src="logo-man.svg" /> </body> <!-- GSAP --> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script> <!-- custom js --> <script src="scripts.js"></script> </html>
  43. 6 points
    Hi, Adobe Animate outputs to canvas. transformOrigin is for a css property for DOM elements. When using Adobe Animate it's important to understand that you can only animate numeric properties of EaselJS Display Objects: https://www.createjs.com/docs/easeljs/classes/DisplayObject.html or values supported by GreenSock's Easel Plugin. In that list you will see regX and regY properties that you can set which is similar to transformOrigin. The regX and regY values are pretty much where the pivot point would be on your Movie Clip. One annoying thing is that if you change the regX or regY it also changes the position of the object. In the demo below I have to offset the position after changing the regX and regY The code below shows how I changed the pivot (or transformation) point. gsap.to(this.default_mc, {duration:3, scale:2, repeat:10, yoyo:true}); this.top_left_mc.regX = 0 this.top_left_mc.regY = 0; this.top_left_mc.x -= 25 this.top_left_mc.y -= 25; gsap.to(this.top_left_mc, {duration:3, scale:2, repeat:10, yoyo:true}); I've attached the fla to this post, but it is also available in my Adobe Animate for HTML5 "not a course" which is a bunch of source files I created to help people struggling with Animate (as I have). change-transformation-point.fla.zip
  44. 6 points
    I have to admit ... I'm baffled by what you're trying to pull off here that couldn't be done with a single timeline.But to answer this question specifically When you set an absolute position on any tween, you affect that specific tween relative to the entire timeline. Any subsequent tweens are still in their natural order. A simple natural order https://codepen.io/sgorneau/pen/BaNwbvb?editors=0010 Here is one tween with a single position out of order https://codepen.io/sgorneau/pen/yLNzwWe?editors=0010 Here is a tween set relative to the prior tween when the prior tween has a position label used https://codepen.io/sgorneau/pen/jOPGJjP?editors=0010 But if you want to shift all subsequent tweens, I would just use a few different timelines and place those timelines in a single master timeline with 0 positions. https://codepen.io/sgorneau/pen/yLNzrNJ?editors=0010
  45. 6 points
    Hey community, Here is the basic equipment: Combined with a walking switch which could be integrated in the smart home environment. In case someone is wondering, the switch is female. And this tree shaking is done by GSAP. My code for Christmas: gsap.to ('. well-being', {duration: 3 days, repeat: -1, yoyo: true, ease: "chillOut"}) ZACH will provide more detailed explanations in the Docs! Merry Christmas ... Mikel
  46. 6 points
    Funny. That's the same date in Back to the Future.
  47. 6 points
    Two alternatives. Use a delayedCall() or a dummy TweenLlite. https://greensock.com/docs/v2/TweenLite/static.delayedCall() const myCallback = function () { // code you want to execute when the time has passed }; const t = TweenLite.delayedCall(time, myCallback); A delayed call returns the TweenLite instance so you can use all the TweenLite/Max methods. A dummy Tween is basically an GSAP instance that takes an empty object as target and does nothing for a specific amount of time: const t = TweenLite.to({}, time, {}); Now you mention this: Seems to me that perhaps you're using a timeline instance (you didn't even provided a small snippet of code so I'm guessing here ), in which case the you can use the dummy instance or event better the position parameter: It would be nice to have some clarification of what you're trying to do. Happy Tweening!!
  48. 6 points
    Hi @Demky and welcome to the GreenSock Forum! That delay is slight and is that element with opacity being put on its own rendering layer after a snapshot has been taken. That is why it only happened on the first load so it can create that new rendering layer from the snapshot. Just keep in mind that if you have one parent, in this case .flip-card-back that has a child with a CSS property that creates a new stacking context.. like opacity. That you will often have to trigger a new stacking context on the parent (.flip-card-back) also, by adding either an old CSS hack of translateZ(0), an opacity: 0.9999999, or other CSS properties that trigger a new stacking context (see the below link). It is the same principle when you have an element with overflow: hidden and its child or parent has a transform or opacity triggering a new stacking context. The parent will not allow overflow: hidden to work unless you also give the parent a new stacking context with one of the CSS hacks. Then the parent will have overflow: hidden work as expected. Google Chrome has more bugs than IE used to ever have. So sometimes you will have to play with the CSS properties of transform-style, and blackface-visibility. But don't forget that Chrome will also act buggy depending on the perspective used. Whether that is the stand alone perspective property or even when you use the transform: perspective() function. I have found that the transform: perspective() function is less buggy than the perspective property in Chrome. The GSAP animation version probably has no issues since it is using matrix3d(), i presume. There is the CSS will-change property but that is a whole other bag of bugs. See @GreenSock (Jack's) explanation of will-change and its crazy behavior of over use. Plus Google Chrome will keep changing behavior of that so use at your own risk. CSS Stacking Context triggers: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context CSS Perspective Property: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective CSS Perspective Function: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/perspective Happy Tweening
  49. 6 points
    Using a letter makes no sense. Numbers are your friend when it comes to repeating something... and so are loops. There are many ways to do a loop, and here is one. https://codepen.io/osublake/pen/c35a7a69af6a6db997249a6111e6f930
  50. 6 points
    @Alex Barak Welcome to the forums and very good question There's several things that should be explained here. The first is that I'd recommend just using a staggerTo along with a yoyo instead of using two separate staggerFromTos. You can then use a repeat value of -1 on it to make sure that they repeat immediately, not waiting for the other staggers to complete before repeating. The next thing is to change the ease from Power0.easeNone to match your CSS animation's ease. So change that to Power1.easeInOut. You also need to keep in mind that while CSS transforms translate elements based on the SVG's height, GSAP translates them based on the height of the element you're animating itself (as is arguably more correct). Thus since you have a translateY of 15%, you need to calculate the appropriate yPercent in GSAP: SVG height * percent = 166px * 0.15 = 24.9px. Then to get that same value as a percentage of the path's height, divide it by the height: 24.9px / 43px = 0.579069767 = 57.9069767%. But in GSAP yPercent assumes that you'll give it a percent, so you can just put the decimal value. The last thing you need to do is change the offset to match the one in the CSS. In the CSS it just divides the total time by 10 to get the offset, so you can do that by just putting the time/10, but I would normally do something like time/paths.length in case you add more elements in the future. Altogether you get something like this: https://codepen.io/GreenSock/pen/vqoveL P.S. You can get all of the elements to start at the beginning by using a negative animation delay
×