Jump to content


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

invisibleEase's Achievements

  1. Awesome news, Jack 🎉! It's great to see this functionality more readily available. Thank you for keeping me posted <3!
  2. Yeah, each format has its tradeoffs. I think it's awesome that the plugin supports all three formats. It'll definitely be extra convenient depending on different animation needs. Thank you so much for solving this Jack.
  3. Thank you for sharing that keys plugin, Jack. I understand the goal should be to keep APIs lean and simple, so ultimately it's up to how many people would use something like this to determine if it's worth adding it to the core. Anyway, I've thought about the issues you anticipated could arise with my suggested implementation, and have made some corrections to my idea. We can think of regular gsap.to tweens as having an implicit 100% keyframe assignment (since all the animated properties inside will reach their written values when the tween's playhead reaches 100%). Building on that idea, we could add support for "keyframe" properties like this: gsap.to(".element", { "0%": { scale: 0.5, opacity: 0 // ...if the "0%" key doesn't exist in the tween, the default behavior of // deriving the starting values from the current property values of the // target element persists }, "75%": { scale: 1.25 // ...if there are no 'in-between' n% keys denoting keyframe steps, the // tween eases to the end state as usual }, scale: 1, opacity: 1, // ...for values that should be reached at 100% of the tween's progress, they // don't have to be nested inside an "n%" key if we're using a gsap.to // tween. // The reverse is true for gsap.from. In that case, what happens at // 0% of the tween's progress doesn't need to be nested inside any key. // This behavior would make current GSAP animations compatible with the new // API by default. duration: 3, // only the tween can have a duration, but keyframes cannot since their starts // are relative to the progress in the duration of their containing tween // (that's why they're defined with percentages) ease: "power1.inOut", // if the tween has an ease, any ease a user may have defined inside a child // keyframe (n% property) is ignored because they're basically overwriting each // other. But, if the parent tween doesn't have its ease property defined, // then each keyframe could have an ease property with a custom easing curve // which would then be animated with an implied duration derived from the // end of the previous keyframe and the duration of the parent tween. // (Check out the next code snippet for an example of this) }); This new syntax addresses this problem because now you just define the percentage you want to add custom values for once, and then you can nest as many properties as you want to animate inside. Keyframe properties (n% keys) could have an onReached() callback function that lets you run any logic you want whenever that percentage of the animation is reached. You could also use that hook to run something like this.pause() to pause the animation at that point and, if you stored the tween in a variable when you defined it, you could then resume it as usual with animation.resume() . If the tween has an ease, it will affect all transitions between each keyframe percentage, just like setting an ease on a CSS animation does, so eases defined inside the keyframes in that tween would be ignored. If a tween with keyframes has a linear ease and a duration of 10 seconds, then the values defined for the "70%" keyframe will be reached exactly after 7 seconds. But, if it has a different ease (like power.inOut or even the more fancy ones like elastic), then 70% of the animation could be reached much faster or slower than 7 seconds. This is how CSS animations already work. If you don't assign an ease to the entire tween, you could do it like this: gsap.to(".element", { duration: 10, "0%": { scale: 0.5, opacity: 0 ease: "power1.in" // ...this ease would have no effect becase the inferred duration // between the start of the tween (0s) and the start of this keyframe // (0% of 10s = 0s) is 0, so it's basically the same as a tween with // no duration. // Adding an ease here probably wouldn't break the animation, but // it'd be best not to add it }, "70%": { scale: 1.25 ease: "power3.out" // ...this ease would have an inferred duration of 7s, which is the difference between // the start of the previous keyframe (0% = 0s) and this one (70% of 10s = 7s) }, "100%": { scale: 1, opacity: 1, ease: "elastic" // ...to add an ease to the last fragment of the animation, we could nest it inside // a keyframe instead of the tween's root. This would help ensure we don't add // an ease to the entire tween that overrides those inside each keyframe we have // defined. Also, now this ease will only affect the transition from the previous // keyframe (70% in this case) to this one. // Its inferred duration is 3s (10s - 7s). // The elastic ease will work in the same way as if we had a gsap.set() for whatever // has been already animated by the preceding tweens, and this one was the first // gsap.to() after that. } }); Removing my comments to offer a cleaner view of the API, the animation from the original post I made would look like this: gsap.to(".circle", { duration: 3, ease: "power1.inOut", yoyo: true, repeat: -1, "0%": { scale: 0.5, opacity: 0 }, "75%": { scale: 1.25 }, scale: 1, opacity: 1 });
  4. Thank you for your detailed response! I really appreciate that you even shared several ways of achieving a similar effect. I love GSAP and writing animations with it feels very natural. For animations like the one in this post, though, it seems very impractical. From what I can see, you now basically have to juggle with the duration of each tween to try to achieve a similar effect. Updating the point at which something happens would mess up the entire animation and you'd have to recalculate the durations of the other tweens to accommodate the change. I imagine you could write some helper functions to set the durations of related tweens automatically for you, but this can quickly get overly obscure for someone unfamiliar with the animation to understand at a glance. I am not sure if this is the right place to suggest an improvement, but it would be phenomenal if you could write tweens like this: timeline.to(".element", { opacity: 1, scale: { "0%": 0.5, "75%": 1.25, "100%": 1 } }); That's so much cleaner and easier to understand, isn't it? Anyway, I really like GSAP so I'll definitely continue to use it. I'll just have to keep using CSS keyframes for animations like this, though. Please let me know if I should move my suggestion somewhere else so it can get to the attention of the right people. Thank you again.
  5. Coming from CSS, I am used to being able to control what happens at a specific point during an animation with keyframe percentages. This is particularly helpful when the change I want to animate doesn't follow a linear pattern from state A to state B, but rather has some variation in between. So, for example, I can do something like this: @keyframes irregular-animation { 0% { transform: scale(0); opacity: 0; } 75% { transform: scale(1.25); } 100% { transform: scale(1); opacity: 1; } } However, I haven't managed to figure out how to do the same with GSAP. In GSAP, it seems I only have control of the start and end states (like with toFrom), but nothing in between. I know I can use custom ease functions to achieve somewhat of a similar effect to the one in the snippet above (whereby I design the easing curve to overextend a little), but this is far from ideal since I often only want to change a single property in this irregular way, not the entire tween. Notice how, in the snippet above, the opacity follows a linear transformation, and it would not make sense to overextend it (even though, for this example, an opacity of, let's say, 1.5 at 75% wouldn't break the animation). Also, it's hard to manipulate a custom curve such that a property reaches a specific value exactly after 75% of an animation is done (or an even less intuitive percentage, like, say, 27%). Timelines are also not ideal for this (from what I've tried, at least), because I want the entire animation to follow along the same easing curve (which is not the same as reusing the same ease in each tween) and, again, it's tricky to calculate when exactly 75% or some other percentage of the overall animation will be done. But maybe I'm missing something... If you had to recreate the simple animation in the CodePen I linked using GSAP, how would you do it? Is it possible to control the values for properties at a specific point during an animation that resembles what we can accomplish with @keyframes in CSS? Thank you for reading. I appreciate any help.