Jump to content


  • Posts

  • Joined

  • Last visited

Contact Methods

Profile Information

  • Gender
  • Location

Recent Profile Visitors

2,092 profile views

lunelson@gmail.com's Achievements




Community Answers

  1. Yeah, that's really one of its main use-cases: implementing the same kind of acceleration and deceleration as you would get with velocity simulation, but with strict duration.
  2. To everyone who followed this topic at the time, I've open-sourced this code now: https://split-ease.netlify.com/ https://github.com/lunelson/split-ease/ ** NB: If anyone wants to do a demo/tryout, please ping me with it on Twitter!! **—I'll assemble a codepen collection or something…
  3. Yeah, that's how you'd do it. Ratios is what the functions currently use. If the total of easeIn and easeOut is greater than 1, they are scaled down proportionally. So, to adapt my previous example, doing absolute easeIn and easeOut times would look like this: // assign a duration const dur = 3; // ...then use it in the duration, easeIn and easeOut arguments; // here, easeIn and easeOut will be 1s each, even if duration is increased TweenLite.to(element, dur, { y:300, ease:MetaEase.power({easeIn: 1/dur, easeOut: 1/dur, pow: 2})});
  4. Yes, the ease function would be possible that way. I know the GSAP docs quote ease functions as having [t,s,c,d] arguments, but this is for sake of compatibility with the original Penner formulations which could interpolate an arbitrary value-change over an arbitrary time-span. So just in case the arguments [time, start, change, duration] are all used by the supplied function, GSAP provides 0,1,1 for the last three, in order to normalize the first, i.e. make time range between 0 and 1; but you can also supply a function that only requires t (time) and simply assumes it to be in the range 0-1, which is the form in which that argument will always be supplied by GSAP's Ease class and by every other JS animation library AFAIK—and the trailing arguments can be simply ignored. In the syntax I propose above, the MetaEase or SplitEase function would be a higher order function that receives an options object and returns a function that accepts that t in the range of 0-1. This is is definitely the syntax I'm leaning toward. But WRT my other point, I wonder if anyone can shed light on how an Ease class might access the duration of the animation it's currently applied to...?
  5. Thanks @OSUBlake, I appreciate your interest! I certainly agree that drawing or defining a complex curve 'by hand' to accomplish this is too much work . One of the things I'm still thinking about is the API. Currently it's configured as a 'standard' easing function, insofar as it takes a 't' parameter in the range of 0 to 1 as its first argument; but because of the additional parameters (inTime, outTime, ?power), you have to wrap it in another function...so it might be better if it was a higher order function to begin with. Some example implementations in a few different libs, as it stands: // tween.js const myTween = new TWEEN.Tween(obj); myTween.easing(t => metaEase.power(t, 0.7, 0.2, 2)); // anime.js anime.easings['myMetaEase'] = t => metaEase.power(t, 0.7, 0.2, 2); // greensock const myMetaEase = new Ease(t => metaEase.power(t, 0.7, 0.2, 2)) TweenLite.to(obj, 5, {x:600, ease: myMetaEase}); In GSAP in particular though, I feel like the ideal API would be something that you could configure 'inline'—perhaps like this // 2.1s ease in, and 0.6s ease-out, as proportions of a 3s duration TweenLite.to(element, 3, {y:300, ease:MetaEase.power({in: 0.7, out: 0.2, pow: 2})}); ...but I think the most interesting would be if the Ease also had access to the duration of the Tween it was applied to, which would offer the possibility of absolute timings of in/out segments, without needing to calculate those proportions yourself. That might look something like this: // fixed 1s ease in and 1s ease out, for any duration >= 2s; otherwise downscaled proportionally TweenLite.to(element, 3, {y:300, ease:MetaEase.power({absIn: 1, absOut: 1, pow: 2})}); Curious to know what you all think of that. Also, whether anyone things the name "SplitEase" is better and/or makes more sense than "MetaEase"...
  6. Thanks Carl, you're right that it's comparable to the eases CustomWiggle and CustomBounce, in particular, in that it generates curves mathematically, that would be difficult (nearly impossible) to draw accurately by hand— however it's not intended to be something other than the classic Penner equations, as much as it is an advancement of them. The quadratic (x^2) ease for example, is still the go-to equation for most movement because it simulates linear acceleration (even if simplistically); but what these equations do, is to use those maths internally while generating a curve in separately-timed segments: so that rather than the classic in/out/inOut options, you can combine in and out segments in any relative proportion to the duration and to each other. Moreover, if the total time/proportion of in and out segments is less than the whole duration, they are joined by a constant-speed segment. This is really the star feature. It supports for example, the use-case of accurately simulating force-based acceleration, travel and deceleration (imagine the way a car goes from point A to point B, over a longer duration), while remaining strictly timed. You're also right that it could generate CustomEase curves; but I see it rather as like RoughEase, configured on the fly with simple arguments. In its current form the in/out arguments represent a proportion relative to the duration, but they could also be absolute timings, e.g. always ease-in for 1s and out for 1s, regardless of duration...
  7. This is a casting for feedback, on something I've had in my junk drawer for a long time. I keep procrastinating on actually releasing it, so I thought I'd see what the community thinks . What I've been calling 'meta-ease' or 'split-ease' is a set of interpolation functions that variably combine acceleration (ease-in), constant-speed and deceleration (ease-out) segments in to a single sine-based or variable-power-based curve. It aims to overcome what I've always felt were limitations of the Penner easing functions on which most animation libs' core easing functions are based, namely (a) that curves which are always either accelerating or decelerating are limiting for longer/slower movements, (b) that easing itself should be able to be as strictly timed as duration, and (c) that quad, cube, quart, quint etc. were a needlessly limited range of options that could easily be combined as one function. This demo has dummy text in it right now but I'm sure everyone here will get the point. It'll be released under an ISC license. Meta-Ease Dummy Preview
  8. Aha! So, on the same tick? I figured it would be scheduled via requestAnimationFrame, and thus happen on the next tick, like when you call requestAnimationFrame from within a requestAnimationFrame handler and it gets scheduled on the next frame...
  9. Thanks Jack! I'll go and think about this some more... I'm guessing, that if I called an update method on a Tween during a tick callback with a priority > 1, that update would happen on the next tick, not on the same one, right?
  10. Thanks, yes I read that too; but was still wondering what exactly "update" meant in this context: ...is this after all values have been internally computed, but nothing yet drawn? Or after drawing updates have been done?
  11. I'm looking at the documentation for TimelineLite.ticker and I'm curious: is it possible to set a priority to the event listener, such that it would be run before tweens and timelines update visually? I'm thinking of, for example, touching the DOM in order to take measurements that might affect a progress parameter, to which timelines refer. Basically read/write or "measure/mutate" batching. addEventListener(type, callback, scope, useParam, priority) Obviously, I can separate this in other ways but let's assume I need to read this value from the DOM just before the tweens and timelines update
  12. Thanks Diaco! It wasn't quite what I meant with the 150 degrees but your construction got the result I was looking for—once I removed the value limits on the draggable items. I'm still not quite sure why if the rotating items used the dragTarget directly, it reacted more slowly than doing it via a dummy div, but using a dummy div it's clear to see that the drag target is just passing through the exact number of pixels dragged. I'll be able to work with this to do what I want! This is what I made, forking from yours: http://codepen.io/lunelson/pen/Byvpvo
  13. Note: compare for example, the effect of dragging the DRAGGER on the circle's rotation, to using the SWIPE area, it's quite different
  14. Hi guys, so this is an alteration of one of the demos Chris Gannon included in his blog post about null objects — I'm using a trigger element, and trying to figure out how ( what logic) the distance dragged on the trigger element is translating in to a rotation of the circle. Dragging the maximum available distance from left to right seems to be able to create about 150 degrees of rotation, regardless of how big the trigger area is. Anyway I'd like to be able to control the 'ratio' by which a drag is translated in to movement: possibly I need to capture the data in a different way? just wondering if someone can tell me the mechanics of what's coming through. Best LN