-
-
Save gre/1650294 to your computer and use it in GitHub Desktop.
/* | |
* This work is free. You can redistribute it and/or modify it under the | |
* terms of the Do What The Fuck You Want To Public License, Version 2, | |
* as published by Sam Hocevar. See the COPYING file for more details. | |
*/ | |
/* | |
* Easing Functions - inspired from http://gizma.com/easing/ | |
* only considering the t value for the range [0, 1] => [0, 1] | |
*/ | |
EasingFunctions = { | |
// no easing, no acceleration | |
linear: t => t, | |
// accelerating from zero velocity | |
easeInQuad: t => t*t, | |
// decelerating to zero velocity | |
easeOutQuad: t => t*(2-t), | |
// acceleration until halfway, then deceleration | |
easeInOutQuad: t => t<.5 ? 2*t*t : -1+(4-2*t)*t, | |
// accelerating from zero velocity | |
easeInCubic: t => t*t*t, | |
// decelerating to zero velocity | |
easeOutCubic: t => (--t)*t*t+1, | |
// acceleration until halfway, then deceleration | |
easeInOutCubic: t => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1, | |
// accelerating from zero velocity | |
easeInQuart: t => t*t*t*t, | |
// decelerating to zero velocity | |
easeOutQuart: t => 1-(--t)*t*t*t, | |
// acceleration until halfway, then deceleration | |
easeInOutQuart: t => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t, | |
// accelerating from zero velocity | |
easeInQuint: t => t*t*t*t*t, | |
// decelerating to zero velocity | |
easeOutQuint: t => 1+(--t)*t*t*t*t, | |
// acceleration until halfway, then deceleration | |
easeInOutQuint: t => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t | |
} |
really awesome and useful!! Thank you!!
Great gist @gre!
I thought it might be helpful to those who wanted to extend the curves to see how that could be done using higher order functions and increasing the power (Thanks to @lindell for the original snippet! This version however removes the unnecessary Math.abs
, reuses easeIn
for the easeOut
function and changes linear
to reference easeIn
rather than easeInOut
to reduce the complexity for each call (although this definitely isn't an exercise in performance))
const easeIn = p => t => Math.pow(t, p)
const easeOut = p => t => 1 - easeIn(p)(1 - t)
const easeInOut = p => t => t < .5 ? easeIn(p)(t * 2) / 2 : easeOut(p)(t * 2 - 1) / 2 + .5
const Easings = {
linear: easeIn(1),
easeInQuad: easeIn(2),
easeOutQuad: easeOut(2),
easeInOutQuad: easeInOut(2),
easeInCubic: easeIn(3),
easeOutCubic: easeOut(3),
easeInOutCubic: easeInOut(3),
easeInQuart: easeIn(4),
easeOutQuart: easeOut(4),
easeInOutQuart: easeInOut(4),
easeInQuint: easeIn(5),
easeOutQuint: easeOut(5),
easeInOutQuint: easeInOut(5)
}
Knowing this, you can re-write @gre's gist like so:
const Easings = {
linear = t => t,
easeInQuad = t => Math.pow(t, 2),
easeOutQuad = t => 1 - Math.pow(1 - t, 2),
easeInOutQuad = t => t < .5 ? Math.pow(t * 2, 2) / 2 : (1 - Math.pow(1 - (t * 2 - 1), 2)) / 2 + .5,
easeInCubic = t => Math.pow(t, 3),
easeOutCubic = t => 1 - Math.pow(1 - t, 3),
easeInOutCubic = t => t < .5 ? Math.pow(t * 2, 3) / 2 : (1 - Math.pow(1 - (t * 2 - 1), 3)) / 2 + .5,
easeInQuart = t => Math.pow(t, 4),
easeOutQuart = t => 1 - Math.pow(1 - t, 4),
easeInOutQuart = t => t < .5 ? Math.pow(t * 2, 4) / 2 : (1 - Math.pow(1 - (t * 2 - 1), 4)) / 2 + .5,
easeInQuint = t => Math.pow(t, 5),
easeOutQuint = t => 1 - Math.pow(1 - t, 5),
easeInOutQuint = t => t < .5 ? Math.pow(t * 2, 5) / 2 : (1 - Math.pow(1 - (t * 2 - 1), 5)) / 2 + .5
}
Although it is much more verbose, hopefully it's easier to understand for those who don't understand the pre-decrement tricks
Finally you can take the previous example and substitute parts of the equations to reference each other (cleaning it up a little bit)
const linear = t => t
const easeInQuad = t => Math.pow(t, 2)
const easeOutQuad = t => 1 - easeInQuad(1 - t)
const easeInOutQuad = t => t < .5 ? easeInQuad(t * 2) / 2 : easeOutQuad(t * 2 - 1) / 2 + .5
const easeInCubic = t => Math.pow(t, 3)
const easeOutCubic = t => 1 - easeInCubic(1 - t)
const easeInOutCubic = t => t < .5 ? easeInCubic(t * 2) / 2 : easeOutCubic(t * 2 - 1) / 2 + .5
const easeInQuart = t => Math.pow(t, 4)
const easeOutQuart = t => 1 - easeInQuart(1 - t)
const easeInOutQuart = t => t < .5 ? easeInQuart(t * 2) / 2 : easeOutQuart(t * 2 - 1) / 2 + .5
const easeInQuint = t => Math.pow(t, 5)
const easeOutQuint = t => 1 - easeInQuint(1 - t)
const easeInOutQuint = t => t < .5 ? easeInQuint(t * 2) / 2 : easeOutQuint(t * 2 - 1) / 2 + .5
Great thread!
@aarongeorge thanks a lot! this is super useful! specifically, recently I was wondering how to generate it to any pow, I used this to something unrelated to easing but to do "distribution" => https://greweb.me/plots/109 (making my lines reaching more the edges)
An alternative (works somehow)
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('f d={c:3(n){0 n},g:3(n){0 n*n},a:3(n){0 n*(2-n)},7:3(n){0 n<.5?2*n*n:(4-2*n)*n-1},9:3(n){0 n*n*n},b:3(n){0--n*n*n+1},e:3(n){0 n<.5?4*n*n*n:(n-1)*(2*n-2)*(2*n-2)+1},k:3(n){0 n*n*n*n},h:3(n){0 1- --n*n*n*n},i:3(n){0 n<.5?8*n*n*n*n:1-8*--n*n*n*n},l:3(n){0 n*n*n*n*n},j:3(n){0 1+--n*n*n*n*n},m:3(n){0 n<.5?6*n*n*n*n*n:1+6*--n*n*n*n*n}};',24,24,'return|||function|||16|easeInOutQuad||easeInCubic|easeOutQuad|easeOutCubic|linear|EasingFunctions|easeInOutCubic|var|easeInQuad|easeOutQuart|easeInOutQuart|easeOutQuint|easeInQuart|easeInQuint|easeInOutQuint|'.split('|'),0,{}))
visual cheat sheet https://easings.net/
This is really good but the easing functions are causing me trouble. I would like the first 75% of the count to go very quickly, and then decelerate to a crawl. I what would the proper function be for this? I imagine something like:
const easeOut = t<.75 ? t => t : [SOMETHING] ;
but I don't know what to put there.
Very helpful!