{{ message }}

Instantly share code, notes, and snippets.

# gre/easing.js

Last active Jun 9, 2021
Simple Easing Functions in Javascript - see https://github.com/gre/bezier-easing
 /* * 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 }

### warpech commented Jun 5, 2013

 Amazing, thanks!

### yairEO commented Aug 26, 2013

 Awesome!!! where can I find more? I want more variety for my code here: http://dropthebit.com/demos/pathAnimator/ Update: I've found this fantastic blog post: http://joshondesign.com/2013/03/01/improvedEasingEquations

### jjwhite commented Oct 25, 2013

 These are great. Thanks!

### gre commented Nov 25, 2013

 @yairEO : basically you can make infinite number of easing with bezier curves, see http://greweb.me/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/

### DanKaplanSES commented Apr 23, 2014

 Nice. What about things like bounce?

### clouddueling commented May 6, 2014

 Does anyone have an example of these in a jsfiddle?

### gre commented May 10, 2014

 Hi @clouddueling, not sure if you are looking for this static easing function or the bezier-easing one ( https://github.com/gre/bezier-easing ) I have a few examples for the bezier-easing one: http://greweb.me/glsl-transition/example/ http://greweb.me/bezier-easing/example/

### bridgetrobs commented Apr 18, 2015

 Awesome, thank you!

### liuda101 commented Aug 4, 2015

 Awesome！ Thank you！

### hvgeertruy commented Aug 20, 2015

 This works. Thanks!

### bjorn-ali-goransson commented Sep 9, 2015

 Suggestion: `````` // acceleration until halfway, then deceleration easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+2*(2-t)*t }, `````` Makes for more consistent style of coding, IMO. Also, here is "decelerate in, accelerate out" easing for quad: `````` // deceleration until halfway, then acceleration easeOutInQuad: function (t) { return t<.5 ? EasingFunctions.easeOutQuad(2 * t) * 0.5 : EasingFunctions.easeInQuad((2 * (t - 0.5))) * 0.5 + 0.5 }, `````` The whole document could be refactored with reusing its own easing functions instead of reimplementing itself repeatedly.

### OrangeBacon commented Nov 3, 2015

 thanks 👍

### DenislavD commented Dec 1, 2015

 This is very helpful.. saved me a lot of time.

### AshCoolman commented Jan 13, 2016

 Thanks!

### AndrewRayCode commented Mar 13, 2016

 Thanks for this! Really don't like the `--t` syntax though. Makes it almost impossible to figure out the order of operations in the functions

### AndrewRayCode commented Mar 13, 2016

 I ES6-ified this and removed the `t--` stuff, which most eslint configs don't like https://gist.github.com/DelvarWorld/940a4a549f9e4c2f262c

### AndrewRayCode commented Apr 4, 2016

 I just open sourced a library of these functions and quite a few others https://github.com/DelvarWorld/easing-utils The source code is heavily cleaned up from this gist to avoid things like inline mutation of variables.

### riccardolardi commented May 12, 2016

 How to use different range, say 1000 to 2000 instead of 0 to 1?

### ghost commented May 19, 2016

 Awesome. tnx. @alberto2000 just multiply your distance with return value.

### lindell commented Jun 21, 2016 • edited

 Made use of higher order functions to make a more general and more compact version. ```EaseIn = function(power){return function(t){return Math.pow(t, power)}}; EaseOut = function(power){return function(t){return 1 - Math.abs(Math.pow(t-1, power))}}; EaseInOut = function(power){return function(t){return t<.5 ? EaseIn(power)(t*2)/2 : EaseOut(power)(t*2 - 1)/2+0.5}}``` So for example, to use EasingFunctions.easeInOutCubic, just write. `EaseInOut(3)(t)` To get a better understanding of how this is used, this is the same as the original gist from @gre ```EasingFunctions = { linear: EaseInOut(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) }```

### kandebonfim commented Aug 30, 2016

 Awsome!

### IllusionSector commented Sep 9, 2016

 What's the simplest way I could implement it? Thanks.

### lvnr commented Sep 29, 2016

 Thank you so much for this!

### dht commented Oct 2, 2016

 Very great

### FiggChristian commented Oct 7, 2016 • edited

 Here's some elastic ones just for fun ```elasticEasings = { // elastic bounce effect at the beginning easeInElastic: function (t) { return (.04 - .04 / t) * Math.sin(25 * t) + 1 }, // elastic bounce effect at the end easeOutElastic: function (t) { return .04 * t / (--t) * Math.sin(25 * t) }, // elastic bounce effect at the beginning and end easeInOutElastic: function (t) { return (t -= .5) < 0 ? (.02 + .01 / t) * Math.sin(50 * t) : (.02 - .01 / t) * Math.sin(50 * t) + 1 } }```

### adiakritos commented Oct 29, 2016

 how do you use these?

### sambeevors commented Nov 16, 2016 • edited

 how do you use these? You just pass t = which is a value between 0 and 1. 0 being the start of the animation, and 1 being the end.

### Kerndog73 commented Nov 18, 2016 • edited

 Here's some sine eases ``` easeInSin: function (t) { return 1 + Math.sin(Math.PI / 2 * t - Math.PI / 2); } easeOutSin : function (t) { return Math.sin(Math.PI / 2 * t); } easeInOutSin: function (t) { return (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2; }```

### bilibiliou commented Jan 24, 2017

 AweSome ! thank you save my life~!!

### victorhqc commented Mar 1, 2017

 Just what I needed :)

### erasmo-marin commented Mar 24, 2017

 this is great!! I'm using it to animate the scroll. If you want to use some ES6 - ES7 syntax, the @lindell version looks like this, a lot more like functional languages: ``` const easeIn = p => t => Math.pow(t, p); const easeOut = p => t => (1 - Math.abs(Math.pow(t-1, p))); const easeInOut = p => t => t<.5 ? easeIn(p)(t*2)/2 : easeOut(p)(t*2 - 1)/2+0.5;``` then use it like this: ``` //power = 3, t = 0.5 let t = easeInOut(3)(0.5);```

### XerxesNoble commented Jun 1, 2017

 Thanks!! I created an animation function that uses these: https://gist.github.com/XerxesNoble/a52e9e430605589224bdc006eb014b38

### AtlasNCz commented Dec 3, 2017

 Great, Thanks1!1!1!

### MostafaOmarIbrahim commented Dec 13, 2017

 Great work, Thank you 👍 <3

### yukulele commented Dec 15, 2017

 typescript class version: https://gist.github.com/yukulele/2234731c0445dd5b1f4673889bf3330c

### ghost commented Jan 12, 2018

 This is awesome! Thanks for this resource!

### ghost commented Jan 24, 2018

 What is `(--t)`?

### RyanG26 commented Jan 26, 2018

 `--` is the decrement operator. It subtracts by one. If placed before a number, it first subtracts 1 then returns the new value. If placed after a number, it first returns the number then subtracts 1.

### wangyi7099 commented Mar 15, 2018

 good! thanks

### alinq commented Jun 3, 2018

 I made the mouse wheel to scroll on the horizontal on a element with this: `document.getElementById('hrz').addEventListener('wheel',event=>this.scrollLeft+=event.deltaY)` Now how do I use EasingFunctions?

### Herohtar commented Nov 9, 2018 • edited

 Since the intended use is `0 <= t <= 1`, isn't `Math.abs(Math.pow(t-1, p))` the same as `Math.pow(1-t, p)`?

### SteverPalm commented Dec 15, 2018 • edited

 I keep getting unexpected behavior with these. Could somebody please tell me what I'm doing wrong? I made a simple example here: https://jsfiddle.net/c2vwa6eb/

### aadityataparia commented Jan 14, 2019

 @SteverPalm it should be `elemToMove.style.left = easeOutQuad(t) * animationDistance + 'px';` instead of `elemToMove.style.left = easeOutQuad(t) * currentDistance + 'px';`

### KilliN-SM commented Feb 17, 2019

 I'm getting spaguetti here, how do I exactly use these functions? Can anyone provide a simple example?

### RienNeVaPlus commented Feb 25, 2019

 2019 speaking, have a version using `export`: https://gist.github.com/RienNeVaPlus/768ce89b83d8e778bbb46868fd26901b

### drone1 commented May 21, 2019

 Bless you child.

### hinell commented Jun 5, 2019

 Bless you God.

### gre commented Jun 6, 2019

 what happened

### HIHIQY1 commented Jun 10, 2019

 I agree, this gist is so helpful!

### vs1998 commented Jul 11, 2019

 @KilliN-SM i used it for easing the movement of an Object on a HTML Canvas: Codepen Easing Example. This pen is also still WIP

### hungdoansy commented Oct 24, 2019 • edited

 Line 23, `easeOutQuart: function (t) { return 1-(--t)*t*t*t },`. Could somebody tell me what's the meaning of `--` ? If it is the Decrement `--`, why is it there?

### chriskirknielsen commented Nov 1, 2019 • edited

 Line 23, `easeOutQuart: function (t) { return 1-(--t)*t*t*t },`. Could somebody tell me what's the meaning of `--` ? If it is the Decrement `--`, why is it there? @dshung1997 The decrement operation mutates the value of `t` so that the three following references to `t` are affected as well. You could write is as `return 1 - (t-1) * (t-1) * (t-1) * (t-1)` and get the same result, but as you can see it's a bit more verbose. You can test this with a little code sample: ```var shortFn = (t) => (1-(--t)*t*t*t); var longFn = (t) => (1 - (t-1) * (t-1) * (t-1) * (t-1)); for (var i = 0; i < 10; i++) { var num = Math.floor(Math.random() * 100) / 100; console.log(shortFn(num) == longFn(num)); }``` Hope this makes more sense for you, now.

### denipriyanto commented Nov 3, 2019

 Hello friend ? how can i get the easing of value process from star and end of easing ?

### frollibas commented Nov 14, 2019

 This is awesome! Can we get easeInOutExpo in the same way?

### Rkokie commented Dec 4, 2019 • edited

 I needed a cubic bezier function to recreate https://cubic-bezier.com/ easing, so I found an article about bezier curves on a canvas and adjusted the code to be a simple timing method. ``````private easeCubicBezier(t, p1X, p1Y, p2X, p2Y) { return 3 * t * Math.pow(1 - t, 2) * p1X + 3 * t * t * (1 - t) * p2X + t * t * t; } `````` p1Y and p2Y are not used but I wanted to reflect the exact parameters the css timing function has.

### kulikvlad commented Dec 5, 2019

 Hello, colleagues, how can I use these formulas to draw graphics on canvas, who has similar material

### tareqdayya commented Dec 7, 2019

 this is awesome man, thanks a bunch

### zenboss commented Dec 12, 2019 • edited

 YOU ARE AWESOME !!!

 👍🎊🔥💯💣

### jwdunn1 commented Jan 4, 2020

 Also useful for easing is the minimum jerk motion of the 'smootherStep' function: `easeInOutSmoother: function(t) { var ts = t * t, tc = ts * t; return 6*tc*ts - 15*ts*ts + 10*tc },` Example: https://jsfiddle.net/intrinsica/9ryqet30 CSS approximation: cubic-bezier(.49,0,.51,1)

### thednp commented Jan 15, 2020 • edited

 @Rkokie I needed a cubic bezier function to recreate https://cubic-bezier.com/ easing, so I found an article about bezier curves on a canvas and adjusted the code to be a simple timing method. ``````private easeCubicBezier(t, p1X, p1Y, p2X, p2Y) { return 3 * t * Math.pow(1 - t, 2) * p1X + 3 * t * t * (1 - t) * p2X + t * t * t; } `````` p1Y and p2Y are not used but I wanted to reflect the exact parameters the css timing function has. Do you happen to have a bezier curve function that uses all 4 values?

### thednp commented Jan 15, 2020 • edited

 @Rkokie I've read the article and came up with a function ```function CubicBezier(cp1x, cp1y, cp2x, cp2y) { let BesierEasingFunction return BesierEasingFunction = t => { let x = 3 * t * Math.pow(1 - t, 2) * cp1x + 3 * t * t * (1 - t) * cp2x, y = 3 * t * Math.pow(1 - t, 2) * cp1y + 3 * t * t * (1 - t) * cp2y return t === 0 || t === 1 ? t : -Math.atan2(x, y) + 0.5*Math.PI; } }``` BUT it doesn't do any interpolation, it just throws some values from time to time, was wondering if you have something that works as an easing function.

### Rkokie commented Jan 15, 2020

 @thednp If you check the article I've posted you'll find the "getBezierXY" method which will use all values, it does require start and end coordinates though. For the timing when easing it appeared making use of all these other parameters didn't make any difference.

### thednp commented Jan 15, 2020

 I replaced sx,sy, with 0 and ex,ey with 1 and I get something moving, but they're not correct.

### Rkokie commented Jan 15, 2020

 I see you're using the "getBezierAngle" function, which doesn't calculate the position in the bezier curve but the angle the curve is at, at a certain point in the curve.

### thednp commented Jan 15, 2020

 I used the other function as well, I still don't get the animation to complete, it's like half the distance and wrong coordinates.

### Rkokie commented Jan 15, 2020

 I'm curious what you're trying to do that isn't fulfilled with the function I posted. Could you whip up an example in codepen or jsfiddle?

### thednp commented Jan 15, 2020

 As you can see, I'm looking for a simple and working easing function for cubic bezier. Something like tween.js could use such.

### thednp commented Jan 15, 2020

 @Rkokie To tell you the truth I'm trying to fix some problem with @gre 's script, join us here.

### jwdunn1 commented Jan 15, 2020

 Not sure how well it works, but try this (found in Ocanvas): ```cubicBezier: function (x1, y1, x2, y2, time) { // Inspired by Don Lancaster's two articles // http://www.tinaja.com/glib/cubemath.pdf // http://www.tinaja.com/text/bezmath.html // Set start and end point var x0 = 0, y0 = 0, x3 = 1, y3 = 1, // Convert the coordinates to equation space A = x3 - 3*x2 + 3*x1 - x0, B = 3*x2 - 6*x1 + 3*x0, C = 3*x1 - 3*x0, D = x0, E = y3 - 3*y2 + 3*y1 - y0, F = 3*y2 - 6*y1 + 3*y0, G = 3*y1 - 3*y0, H = y0, // Variables for the loop below t = time, iterations = 5, i, slope, x, y; // Loop through a few times to get a more accurate time value, according to the Newton-Raphson method // http://en.wikipedia.org/wiki/Newton's_method for (i = 0; i < iterations; i++) { // The curve's x equation for the current time value x = A* t*t*t + B*t*t + C*t + D; // The slope we want is the inverse of the derivate of x slope = 1 / (3*A*t*t + 2*B*t + C); // Get the next estimated time value, which will be more accurate than the one before t -= (x - time) * slope; t = t > 1 ? 1 : (t < 0 ? 0 : t); } // Find the y value through the curve's y equation, with the now more accurate time value y = Math.abs(E*t*t*t + F*t*t + G*t * H); return y; }``` The time parameter varies from 0 through 1, returning the corresponding y value.

### thednp commented Jan 15, 2020

 @jwdunn1 nop, but I thank you for the code.

### jwdunn1 commented Jan 15, 2020 • edited

 The UnitBezier function in this CodePen tracks somewhat closely to the CSS cubic-bezier transition timing function: https://codepen.io/jwdunn/pen/VJGzNm

### thednp commented Jan 16, 2020 • edited

 @Jdunn1 confirmed, the UnitBezier kicks some punch and it moves pretty fast as well, thank you.

### thednp commented Jan 16, 2020

 @jwdunn1 if you're looking for an ES6 version, here's one.

### MisterSirCode commented Jan 17, 2020

 Tip, you should convert them to arrow expressions, and dont minify, this is 2020, we dont need minification :D ALSO you seemed to forget the "var" part of the EasingFunctions variable. ```var EasingFunctions = { // no easing, no acceleration linear: t => { return t; }, // accelerating from zero velocity easeInQuad: t => { return t * t; }, // decelerating to zero velocity easeOutQuad: t => { return t * (2 - t); }, // acceleration until halfway, then deceleration easeInOutQuad: t => { return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; }, // accelerating from zero velocity easeInCubic: t => { return t * t * t; }, // decelerating to zero velocity easeOutCubic: t => { return --t * t * t + 1; }, // acceleration until halfway, then deceleration easeInOutCubic: t => { return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; }, // accelerating from zero velocity easeInQuart: t => { return t * t * t * t; }, // decelerating to zero velocity easeOutQuart: t => { return 1 - --t * t * t * t; }, // acceleration until halfway, then deceleration easeInOutQuart: t => { return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; }, // accelerating from zero velocity easeInQuint: t => { return t * t * t * t * t; }, // decelerating to zero velocity easeOutQuint: t => { return 1 + --t * t * t * t * t; }, // acceleration until halfway, then deceleration easeInOutQuint: t => { return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t; } };```

### gre commented Jan 17, 2020 • edited

 @skylerspark done! it's a snippet, up to you to `var` it or `const` it or `module.exports=` it or `export default` it ;)

### mhaidarhanif commented Feb 23, 2020

 @gre Very useful! Thank you very much, Gaëtan!

### temm1210 commented Jul 29, 2020

 really awesome and useful!! Thank you!!

### aarongeorge commented Oct 5, 2020 • edited

 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```