Jump to content
GreenSock

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

Leaderboard

  1. ZachSaucier

    ZachSaucier

    Administrators


    • Points

      410

    • Content Count

      3,845


  2. GreenSock

    GreenSock

    Administrators


    • Points

      396

    • Content Count

      14,817


  3. OSUblake

    OSUblake

    Moderators


    • Points

      276

    • Content Count

      5,699


  4. PointC

    PointC

    Moderators


    • Points

      123

    • Content Count

      3,812



Popular Content

Showing content with the highest reputation since 06/10/2020 in all areas

  1. 10 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. 8 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!
  3. 7 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?
  4. 6 points
    Congrats on your new journey, can't wait to take part in it! Your "first year of gsap" post moved me so much... and your work inspires me on a regular basis. I don't even know how to express my gratitude for you sharing all this with us. What a fitting way for you now to spread your passion on to the future.👏
  5. 6 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 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 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's That Pokémon? - forEach example demo by GreenSock (@GreenSock) on CodePen. 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!
  6. 5 points
    Check this out - just released today: https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.scrollerProxy()
  7. 5 points
    @Carl let's give Blake 12 months and if he doesn't get it done, we'll collaborate on a new site and take all the fortune and glory for ourselves. I should probably register the domain before someone else grabs it. snorklmotionpixicodingcreativetricksclubbecauseblakedidntwanttodoit.com
  8. 5 points
    Well yeah. I just didn't want to be rude. I have to write more????? 👀 I'm unofficially planning for 'New Tutorial Tuesdays'. Should fit nicely with taco Tuesday. 🌮
  9. 5 points
    You can use keyframes if you're using the same target. https://codepen.io/osublake/pen/5a8c8feb233e5bcd66b87b40be8095ac
  10. 5 points
    Congrats buddy, looks amazing. True to your tradition here is a gif to celebrate the launch:
  11. 5 points
    It's the drop area where the scrolling works. Not the container with the images. If you've already created a scroller, and it's all done with svg, then it sounds like most of the stuff in those demos probably won't apply to your use case. Those demos were to show how to drag something out of scrolling container because you literally can't drag something out of it. But if you're using SVG, you can certainly drag stuff anywhere as long as overflow is visible. If you need to clip stuff, you can use a clipPath or mask. Draggable can definitely help simplify a lot of code, and it's been battle tested to handle a bunch of different edge cases. My first thought would be to create a clone of what you dragging, and then manipulate the viewBox to move the items in the direction you want it scroll. If not the viewBox, then make sure everything is inside a <g> element, and translate it. You can read the deltaX and deltaY properties in your onDrag callback, and use those values to scroll your container if need. https://greensock.com/docs/v3/Plugins/Draggable/deltaX
  12. 5 points
    Yep, @mikel is using the approach I typically do for something like this. There are actually a bunch of ways to accomplish this. The gist is: function animate() { gsap.to(".class", { ... duration: gsap.utils.random(0.5, 3), // random number between 0.5 and 3 onComplete: animate // this is what does the infinite loop }); } animate(); // kick it off In the upcoming release of 3.4.0, you'll be able to do this instead: gsap.to(".class", { ... duration: gsap.utils.random(0.5, 3), repeat: -1, onRepeat: function() { this.duration( gsap.utils.random(0.5, 3) ); } }); (not that it's any better - just an alternative) By the way, @b1Mind, I hope you don't mind me pointing out a few things with your code... You almost never need to wrap your CSS-related values in a css:{} object. GSAP is smart enough to figure that stuff out these days and it tends to make your code less readable. Timelines can't have a duration set via the vars. They just conform to however long their children are. Think of timelines like wrappers around tweens. So if you shove a 10-second tween into a fresh timeline, that timeline will have a duration of 10 seconds. Add another 5-second tween to the end, and it's now 15 seconds. If you set the duration via the setter method like timeline.duration(5), that merely alters the timeScale accordingly. You don't need to do something like Math.floor(Math.random() * 100) - you can tap into GSAP's utility method like gsap.utils.random(0, 100, 1) To get a random color, you could tap into GSAP's inline random capability (it'll search inside strings for "random(...)" and swap in values), like: color: "rgb(random(0,255,1), random(0,255,1), random(0,255,1))". Happy tweening!
  13. 5 points
    I'm not sure about your math. Like why are you calculating angles? To see if a point is inside a circle... // assumes x and y coords are the center const dx = Math.abs(cursor.x - bubble.x); const dy = Math.abs(cursor.y - bubble.y); if (dx > attractRadius || dy > attractRadius) { // not inside } Here's how I'd do it. The bubbles aren't animating, but it makes no difference. It will work the same. https://codepen.io/osublake/pen/ae04f1f23935e7d7a13c823d6141dec2 I didn't account for the delta, but here's how to do that.
  14. 5 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.
  15. 5 points
    FYI, GSAP can do that for you. gsap.utils.shuffle(). So... gsap.utils.shuffle(gsap.utils.toArray(".item")).forEach(...);
  16. 5 points
    If you need more than 1 image, you would need to use a sprite sheet so there is only 1 baseTexture. Sometimes codepen sends the wrong headers. Just need to clear the cache by adding something like ?v=1 to the end of the image url.
  17. 5 points
    Hey HawkMusician. You're right, the markers are not currently removed if it's killed. But does it really matter? Markers are just for development purposes and adding code to remove them would add more file size to the file for everyone always. I'm not saying that we won't end up adding this to ScrollTrigger, just wondering why you'd say it's something that needs to be fixed
  18. 5 points
    Hi, This works with a class component: https://codesandbox.io/s/gsap-react-stop-wheel-h6fpv?file=/src/App.js The approach is a bit different though. You'll have to find a correlation between the end angle and the actual landing spot of the wheel, or try to implement your own logic for that. Also I don't know what on earth is going on in Codesandbox but the same code is working as expected here: https://gsap-stop-wheel.netlify.app/ Here works as expected too: https://stackblitz.com/edit/gsap-react-stop-wheel?file=index.js Happy Tweening!!!
  19. 5 points
    It depends on how many elements we're talking about here. If it's just a few copies, I'd echo Zach's advice and prep your artwork in your vector software. If you have hundreds of elements, cloning is one way to go. Here's a simple clone loop. https://codepen.io/PointC/pen/24b436be30b10bd6fc5b840c913b9db6 Or you can create everything on the fly. Here's that option. https://codepen.io/PointC/pen/ac3cac6818d6711f183884373e20fc6b
  20. 5 points
    Aha, your test case revealed an issue in ScrollTrigger - you were using toggleClass and when refreshing, it wasn't removing the class before calculating the positions. Your class was affecting positioning, hence the problem. Each time you clicked "refresh" it was basically toggling the class on that element back and forth. Thanks for the reduced test case! It made it much quicker to identify the issue. I made that change for the next release which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js (you may need to clear your cache) - does that work better for you? By the way, toggleActions are totally pointless if you don't have an animation linked to the ScrollTrigger. And it's absolutely fine to set up a ScrollTrigger without an animation. It's quite useful in fact. I'm just saying it's a waste to define toggleActions because those just tell ScrollTrigger what to do to the associated animation.
  21. 4 points
    You don't need to @ people. You shouldn't use new for timelines. It's not a constructor. // BAD var tween1 = new gsap.timeline(); // GOOD var tween1 = gsap.timeline(); You also don't need timelines for a single animation. Why don't you just create a list of the properties to animate? var animationData = [ { x: 10 }, { x: -10 }, { x: 20 }, { z: 15 }, { x: 15 } ]; tweenArr.forEach((node, i) => { var settings = Object.assign({ duration: 10, ease: "none" }, animationData[i]); gsap.to(node.position, settings); });
  22. 4 points
    Hi @Tonycre8, I have put together this simple guide on how to use GreenSock together with React Hooks. Hope you will find it useful. Cheers
  23. 4 points
    Yeah, with GSAP 3 you have many more options for staggering. Check out this video on the stagger object which lets you stagger from "end" and "center" animation.from(split.chars, {opacity:0, y:50, ease:"back(4)", stagger:{ from:"end", each:0.05 }}) Demo here: https://codepen.io/snorkltv/pen/BajxopX
  24. 4 points
    What mikel said, but I'd recommend this toggleActions: "play none none reverse".
  25. 4 points
    Hi @dlsmoker, I think what you're missing the the pause play functionality. So something like: const tl = gsap.timeline({ paused: true }); // inside button click function tl.play(); // inside close overlay function tl.pause(0); As for ScrollTrigger, that functionality is built into it. So animations are automatically played/paused there. I'd highly recommend looking over the docs, and learning center: https://greensock.com/docs/ https://greensock.com/learning/
  26. 4 points
    We've always allowed other methods. Attach a zip, link to a repo, it doesn't matter. It's just faster to test, experiment, and iterate using an online editor that can be forked. And again, if codepen isn't working, then try codesandbox or stackblitz. I actually prefer them over codepen. What we don't want to see is live sites and projects with thousands of lines of code. Just the bare minimum needed to reproduce the problem.
  27. 4 points
    You only need to do that because there is a delay when the 2nd and 3rd animations start. They are essentially paused, so it's not going to jump to the first animation frame before it starts.
  28. 4 points
    The default duration is 0.5s. Change it to something higher. And set your objects to the start position so they don't jump. gsap.set(cabezas, { x: -r, }); gsap.to(cabezas, { motionPath: { path: `M ${-r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0z` }, ease: "none", duration: 1, stagger: { repeat: -1, each: 0.2 } });
  29. 4 points
    Because it's so beautiful and fun ... https://codepen.io/mikeK/pen/xvygbQ
  30. 4 points
    TweenLite, TweenMax, TimelineLite, and TimelineMax are deprecated. You should use the new syntax.
  31. 4 points
    <div class="moveMe"> <h1> Hi world </h1> </div> // then gsap.from('.moveMe',{ opacity:0,y:200,duration:5 }); @Lichay Your issue is in specificity. GSAP does not break your css, it is applying a inline transform to your element (cause that's what it does). So you need to split up your transform, maybe have gsap animate a parent element. Then have your hover on the h1.
  32. 4 points
    Create a test and find out. var div = document.querySelector("div") var style = getComputedStyle(div) console.log(style.visibility) gsap.to(div, { visibility: "hidden", onUpdate() { console.log(style.visibility) } })
  33. 4 points
    You're gonna love what's coming in version 3.4. There's a new matchMedia() method that does EXACTLY what you're talking about here. This is an example: https://codepen.io/GreenSock/pen/GRoyWBd We hope to release 3.4 within the next week. You're welcome to use the beta in the mean time if you'd like. https://assets.codepen.io/16327/ScrollTrigger.min.js Does that help?
  34. 4 points
    Oh, you mean like this?: https://codepen.io/GreenSock/pen/rNxpbyX?editors=0
  35. 4 points
    Hard to say what if any performance problems there might be without seeing a demo. The quickSetter just set values, so maybe you are mistaking that for performance problems. 🤷‍♂️ If you need a smooth transition, then you can interpolate changes like in this demo. https://codepen.io/GreenSock/pen/WNNNBpo And the most performant way to use quickSetter is to specify the property. this.hillsXSetter = gsap.quickSetter(this.hills, 'x', 'px') this.hillsXSetter(s / 5) Also, setting will-change: transform in your css for the images can improve performance.
  36. 4 points
    I would put the timeline on the instance using this. export const homeTweens = { mounted() { this.introTl = gsap.timeline() .from( this.$refs.separador1, { duration: 0.8, xPercent: -100, } ) .from( this.$refs.mouseContainer, { duration: 0.9, yPercent: 100, autoAlpha: 0, }, "<" ) .from( this.$refs.nombre, { duration: 0.5, yPercent: 10, autoAlpha: 0, }, "<" ); }, beforeRouteLeave(to, from, next) { this.introTl.reverse().eventCallback("onReverseComplete", function() { this.introTl.kill(); this.introTl = null; next(); }); }, };
  37. 4 points
    Hard to say without seeing your code. Are you adding animations to the data object? I normally put animations on the instance itself. The data object is for reactive stuff. Adding animations to it creates more overhead.
  38. 4 points
    Hi! You use old syntax (better use gsap.to not TweenMax) Better use ScrollTrigger, not ScrollMagic ScrollMagic is not GSAP plugin If you want better answers please create simple demo on codepen
  39. 4 points
    No worries, happy to help. GSAP3 has a new syntax so gsap.to() is a new way of doing TweenLite.to() Checkout the docs for the new GSAP3 syntax.
  40. 4 points
    I don't think you are doing anything wrong with the refs, but I would tweak it slightly. Here is a working demo, hope that helps. https://codepen.io/ihatetomatoes/pen/MWKmJaY
  41. 4 points
    FYI I just updated the pen with some comments if that helps Happy tweening.
  42. 4 points
    There are no shapes in this demo. It's all images. https://codepen.io/osublake/pen/c70ff0dcd68fc1581dbf8b335fb60c3b If you have more than 1 sprite, you should put them in an array just like the demo above. function render() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i; i < sprites.length; i++) { var sprite = sprites[i]; context.save(); context.translate(+sprite.x + sprite.offsetX, +sprite.y + sprite.offsetY); context.rotate(sprite.rotation * toRad); context.drawImage(sprite.texture, -sprite.offsetX, -sprite.offsetY); context.restore(); } }
  43. 4 points
    I like creating objects that have simple methods I can call (object-oriented), and you can store them all in an Array, like allButtons which you could then loop through whenever you want and call pause() on each one for example: https://codepen.io/GreenSock/pen/39ee309f458fe8f35d16c8024e0c52ba?editors=0010 Does that help?
  44. 4 points
    No problem: https://codepen.io/GreenSock/pen/mdVEpKK?editors=0010 Notice how much easier it is. One tween. Done! No fancy SCSS necessary, no looping through and creating a bunch of ScrollMagic Scenes, etc. Does that help?
  45. 4 points
    I've done it! Thanks GSAP for the great product! https://codepen.io/laurensiusadi/pen/ExPPgVm
  46. 4 points
    I feel like I'm contributing when I answer my own questions haha. I did find this tip from @PointC which was a quick Illustrator fix without having to code 2 sets of line animations: "Quick tip: when you create your path, place a temporary arrowhead on the beginning of it via the stroke panel in your vector software. If the direction is incorrect, you can easily reverse it. In Adobe Illustrator you do that by the menu Object --> Path --> Reverse Path Direction. Once it's going in the desired direction, simply remove the arrowhead and export."
  47. 4 points
    Yep, @PointC is exactly right (if I understood you correctly). Here's a fork that shows a dynamic version that plots however many dots you have around the center, and staggers their animation: https://codepen.io/GreenSock/pen/65c751a4229fc3068c5bde433aee915d?editors=0010 I think you'll find that GSAP 3 lets you do a lot more with less code. 👍 Does that help?
  48. 4 points
    You want the animation to restart when it enters in the backwards direction? Just use the toggleActions: // order: onEnter onLeave onEnterBack onLeaveBack toggleActions: "restart pause restart none", Is that what you're looking for?
  49. 4 points
    You can hide scrollbars by making the inner container larger than the outer one. https://codepen.io/osublake/pen/1ab3cd4e2e03fc029cdd510b0358d5b4
  50. 4 points
    When you don't want the svg to scale, so it's a fixed size. I think this is a good svg resource. http://tutorials.jenkov.com/svg/svg-viewport-view-box.html
×