Spicy Yoghurt | Last updated: 19 October 2026
Easing functions for JavaScript and CSS
Find the right JavaScript or CSS easing function for your animation or game. Pick an easing per axis, watch the motion and copy the code. With graphs, JS code and CSS values for all 31 easing functions, from ease-in-out to elastic and bounce.
What is an easing function?
In games and animations, things move all the time. You can move an object from A to B at the same speed all the way, but that looks a bit stiff. Nothing in real life moves like that. A ball slows down before it stops, and a car needs some time to speed up.
An easing function fixes that. It takes the progress of an animation, a number from 0 at the start to 1 at the end, and bends it. The result still starts at 0 and ends at 1, but in between it goes faster or slower. That's what makes a motion feel natural, or bouncy, or springy.
This page is all about the easing functions themselves, with a tool to try them out and the code for all of them, in JavaScript and CSS. Want to know how to use easing in your game, step by step? Then check out the tutorial about how to create a smooth canvas animation. It shows you how to move objects on the canvas with a game loop, and how to add easing.
Animation tool for easing functions
The tool below helps you find the right easing for a motion in your game or animation. Instead of guessing from a formula, you see the motion itself: how an object moves from A to B, with a different easing on each axis if you like. When it looks right, you can copy the code.
The code for this motion is under the tool. It changes with every click and with every easing you pick. Use the tabs to switch between the modern form with one argument (t), the classic form with four (t, b, c, d) and the same motion in CSS.
Click anywhere on the canvas and the circle moves there, with the easing you pick for each axis:
const duration = 1;
let timePassed = 0;
function update(secondsPassed) {
timePassed += secondsPassed;
// Progress from 0 (start) to 1 (end)
let t = Math.min(timePassed / duration, 1);
x = lerp(60, 690, easeLinear(t));
y = lerp(60, 340, easeOutBounce(t));
}
// Go from a to b, with t from 0 to 1
function lerp(a, b, t) {
return a + (b - a) * t;
}
function easeLinear(t) {
return t;
}
function easeOutBounce(t) {
// A fall and three bounces, each one lower than the one before
const n = 7.5625;
const d = 2.75;
if (t < 1 / d) {
return n * t * t;
} else if (t < 2 / d) {
t -= 1.5 / d;
return n * t * t + 0.75;
} else if (t < 2.5 / d) {
t -= 2.25 / d;
return n * t * t + 0.9375;
} else {
t -= 2.625 / d;
return n * t * t + 0.984375;
}
}How to use this animation tool?
The tool shows what an easing does to a real motion, on both the x- and y-axes:
- Click the canvas - Pick a new end point. The circle moves there, and the trail shows its path.
- Pick an easing for each axis - Choose a function for the x-axis and the y-axis, and a variation: in, out or in-out. Or click Randomize for a surprise.
- Copy the code - The code under the tool changes with every choice. Pick the form you like with the tabs, and click the copy button in the corner to use it in your own game.
The dots of the trail are spread evenly in time. Just like in the graphs below, the circle moves fast where the dots are far apart. Play around with the tool until you find the motion you're looking for.
How to use the code in your game
The code from the tool works in any game loop. Here's what it looks like with an easing on the x-axis only:
const duration = 1;
let timePassed = 0;
function update(secondsPassed) {
timePassed += secondsPassed;
// Progress from 0 (start) to 1 (end)
let t = Math.min(timePassed / duration, 1);
x = lerp(200, 500, easeOutQuad(t));
}
// Go from a to b, with t from 0 to 1
function lerp(a, b, t) {
return a + (b - a) * t;
}First, the time that has passed is turned into a progress from 0 to 1. Math.min() makes sure it stops at 1, so the object stays at the end. Then the easing function bends the progress, and lerp() turns it into a position between 200 and 500. lerp() is short for linear interpolation, and you'll find it in just about every game engine.
Let's check the numbers. Halfway through, the object without easing is at 350, right in the middle as you would expect. The object with easing is already at 425 around that time and slows down for the rest of the way:
Where does secondsPassed come from? That's the time since the previous frame, and you measure it in your JavaScript game loop. The tutorial below shows the whole thing in action, with an animation on the canvas.
Animations in HTML5
Create a smooth canvas animation
Move objects on the canvas, relative to time, and add easing. Step by step, with live examples.
You can ease more than a position. Any number will do: the size of a coin that pops up, the opacity of a menu that fades in, or the zoom of your camera.
Here's a camera that zooms in on the player. The zoom and the position of the camera use the same easing, so they arrive at the same moment:
// From the whole level to twice as close, with the player in the middle
let ease = easeInOutCubic(t);
let zoom = lerp(1, 2, ease);
let cameraX = lerp(canvas.width / 2, player.x, ease);
let cameraY = lerp(canvas.height / 2, player.y, ease);
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Zoom in around the camera position
context.translate(canvas.width / 2, canvas.height / 2);
context.scale(zoom, zoom);
context.translate(-cameraX, -cameraY);
drawWorld();setTransform() resets the zoom and the position at the start of every frame. The three lines after clearRect() put the camera position in the middle of the canvas, and scale everything around it. Here is the result:
So easing isn't just for moving things around. Be creative, and try it on anything else in your game, like a health bar that drains or music that fades out. The tutorial about smooth canvas animation has more examples, like easing the size, rotation, opacity and color of an object.
Which easing function should you pick?
First, there's the variation. Use ease-out for things that arrive or react, ease-in for things that leave, and ease in-out to move from one spot to another. When in doubt, pick ease-out.
Then there's the family. You'll find them all in the list with graphs at the bottom of this page. The basic ones only differ in how strong the effect is. From soft to sharp:
- Sine - Very soft, close to linear. Nice for things that float or sway.
- Quad - The progress to the power of 2. A good choice for most motion.
- Cubic - The power of 3. A bit snappier, great for menus and buttons.
- Quart and Quint - The power of 4 and 5. A fast start and a long, smooth stop.
- Expo - The sharpest of all. Almost the whole motion happens at once.
- Circ - Based on a quarter of a circle, with a very sudden start or stop.
And then there are three with a character of their own:
- Back - Goes a little past the end and comes back. Great for anything that pops up.
- Elastic - Wobbles like a spring before it settles. Nice for things that snap into place, like a speech bubble or a toggle switch.
- Bounce - Bounces like a ball that hits the floor. Perfect for things that fall and land.
For a game, keep the easings short. When the player does something, the motion should take about 0.1 to 0.4 seconds, or the game starts to feel slow. That's also what Nielsen Norman Group advises for animations in apps and websites. Save the long and dramatic ones for a title screen or a level that's complete.
Different easings on the x- and y-axes
Here's where it gets interesting. The x- and y-position of an object don't need the same easing. Use a different one for each axis and the object follows a curved path instead of a straight line.
Here are some examples:
- Jump - A player that jumps onto a higher platform moves forward at the same speed, goes up, slows down and comes down a little to land. That's linear on the x-axis and ease-out back on the y-axis. The ease-out back easing goes just past its end and comes back, so the player lands on the platform from above.
- Bounce - For a ball that bounces on the floor, use ease-out bounce on the y-axis.
- Collect a coin - A coin that you collect can fly to your score. With ease-in back on the x-axis it first moves back a little, and with ease-out quad on the y-axis it shoots up before it curves to the corner.
- Swoop - With ease-out on one axis and ease-in on the other, you get a nice swoop, like a player with wings that dives down onto a coin.
Let's check them out in the canvas below. Click an example to play it. The tool at the top of the page switches to the same easings, so you can copy the code there.
Easing functions with four arguments
Look around for easing functions and you'll often find ones with four arguments instead of one: (t, b, c, d). They come from Robert Penner, who wrote the classic set of easing equations back in the days of Flash. Almost every easing library is based on his work, and so are the functions on this page. Here's what the four arguments mean:
- t = Time - The time that has passed since the start of the animation.
- b = Beginning value - Where the animation starts, like an x-position of 200.
- c = Change in value - How much it changes from start to end, like 300 pixels to the right.
- d = Duration - How long the animation takes, in the same unit as t.
These functions do the lerp() for you, but the curve is exactly the same. In fact, you can turn any easing with four arguments into one with a single argument:
// The same as easeOutQuad(t, b, c, d) with four arguments
x = b + c * easeOutQuad(t / d);So why use the more modern version with one argument? It's shorter and easier to read, and it doesn't care what you animate or which unit of time you use. It's also how CSS, most animation libraries and game engines like Phaser work these days.
Do you need the old form anyway, for code that already uses it? Use the Classic tab above the code, under the tool or in the list below, and you'll get the original functions from the Flash era.
Easing functions in CSS
Animating HTML elements instead of a canvas? Then you don't need JavaScript for easing. CSS has transition-timing-function for transitions and animation-timing-function for animations with @keyframes. Five easings are built in:
- linear - The same speed from start to end.
- ease - Starts quite fast and slows down a lot at the end. This is the default, so it's what you get when you don't pick an easing.
- ease-in - Starts slow and speeds up.
- ease-out - Starts fast and slows down.
- ease-in-out - Slow at the start and at the end.
Click the buttons below to compare them, together with Spicy Yoghurt's own Back and Bounce easings. The ball is a plain HTML element that moves with a CSS transition:
.ball {
transition: transform 1s ease;
}How does CSS cubic-bezier() work?
The five built-in easings of CSS are all a cubic-bezier() under the hood. ease-out, for example, is cubic-bezier(0, 0, 0.58, 1). The four numbers are two points that bend the curve: (x1, y1) and (x2, y2). The curve always starts at (0, 0) and ends at (1, 1), just like the graphs on this page.
- x1 and x2 - The time. These have to be between 0 and 1.
- y1 and y2 - The progress. These can go below 0 or above 1, and that's how an easing goes past its end.
Here are ease-out cubic and ease-out back, on a menu that slides in. The parameters of cubic-bezier() are pre-calculated to match each easing, so you don't have to calculate them yourself. The second curve makes the menu go about 10% past its end before it settles:
.menu {
transition: transform 0.4s cubic-bezier(0.33, 1, 0.67, 1);
}
.menu.bouncy {
transition: transform 0.4s cubic-bezier(0.33, 1.56, 0.66, 1);
}Here are both curves in action. The two blue dots are the points (x1, y1) and (x2, y2). Drag them to make a curve of your own, and copy the value below:
cubic-bezier(0.33, 1.56, 0.66, 1)Most functions in the list below come with their value for cubic-bezier(). For the strong ones, like quintic and exponential, the match isn't exact, but it comes extremely close: about 1% off at most, which is hard to see. A curve with four numbers can only bend so much, so that's the same for every cubic-bezier() version of these easings. There's more about the precision in the question section further down this page.
Want to animate an HTML element from JavaScript? The Web Animations API takes the same values:
menu.animate(
[{transform: 'translateX(-100%)'}, {transform: 'translateX(0)'}],
{duration: 400, easing: 'cubic-bezier(0.33, 1, 0.67, 1)'}
);Bounce and elastic in CSS with linear()
A cubic-bezier() curve can go past its end once, but it can't bounce or wobble. For that, there's linear(). It takes a list of points, and the browser connects them with straight lines. With enough points, that looks just as smooth as the real thing. Here's ease-out bounce:
.ball {
transition: transform 1s ease-out;
transition-timing-function: linear(
0, 0.016 4.55%, 0.062 9.05%, 0.14 13.6%, 0.249 18.15%, 0.39 22.7%,
0.562 27.25%, 0.765 31.8%, 0.999 36.35%, 0.889 41%, 0.812 45.5%,
0.766 50%, 0.75 54.55%, 0.765 59.05%, 0.812 63.6%, 0.889 68.1%,
1 72.75%, 0.953 77.3%, 0.938 81.85%, 0.953 86.35%, 1 90.9%,
0.984 95.45%, 1
);
}Let's check it out in the canvas below. The red dots are the points of linear(), with straight lines in between. The thin gray line is the real easing function, and you can hardly tell them apart:
Each point is a progress, with the moment in time as a percentage. You don't have to work these out yourself: the list below has a value with linear() for elastic and bounce, and for ease in-out back and circular, where a cubic-bezier() isn't close enough.
So where do these points come from? We've analyzed each easing function at 2,000 moments in time and compressed the results to as few points as possible, with an accuracy of 99.5% or higher.
You'll also find bounce and elastic easings on easings.net. They use @keyframes for those, and that's quite a bit less precise. Ease-out bounce, for example, is up to 19% off there. The linear() values here at Spicy Yoghurt are a lot more precise.
linear() has worked in all modern browsers since the end of 2023 (Chrome and Edge 113, Firefox 112 and Safari 17.2). An older browser skips the line it doesn't know, so it keeps the ease-out above it. You can read more about it on MDN.
Sprite animations in CSS with steps()
There's one more easing in CSS: steps(). It doesn't move smoothly, but jumps from one step to the next. That's just what you need for a sprite sheet: with steps(8), the background jumps through the eight frames of a walking character:
.player {
width: 64px;
height: 64px;
background: url(walk.png);
animation: walk 0.8s steps(8) infinite;
}
@keyframes walk {
to {
background-position: -512px 0;
}
}Here it is in action. The red frame is the part of the sprite sheet you see, and it jumps to the next frame eight times in 0.8 seconds:
On the canvas, you do the same thing by drawing a different part of the image every frame. The tutorial about images and sprite animations shows you how.
Common questions about easing functions
What is the difference between ease-in and ease-out?
Ease-in starts slow and speeds up. Ease-out starts fast and slows down at the end. Ease-out feels the most natural for things that appear or come to a stop, so it's a good choice when you're not sure.
Which easing function should I use in a game?
Ease-out quad or cubic for most motion and menus, ease-out back for things that pop up and ease-out bounce for things that land. Keep it short, about 0.1 to 0.4 seconds, for anything the player does.
Do I need a library like GSAP?
Not for a canvas game: an easing function and lerp() are just a few lines of code. A library comes in handy when you animate a lot of HTML elements, with timelines and sequences.
Why does my object move past the end of the animation?
Because the time has gone past the end. Every easing function keeps going when t gets bigger than 1, so the object moves too far or even comes back. You can stop that with Math.min(), which gives you the smaller of two numbers:
// t goes from 0 to 1, and then stays at 1
let t = Math.min(timePassed / duration, 1);For the classic functions with four arguments, do the same with the time: Math.min(timePassed, duration).
What is a spring animation?
An animation that works like a spring, with a stiffness and a damping instead of a fixed duration. It reacts in a natural way when you interrupt it, so a lot of app interfaces use it. Elastic comes close, and in CSS you can mimic a spring with linear().
Does the easing work over the whole animation with @keyframes?
No, it works from one keyframe to the next. Say a ball moves 400 pixels, with an extra keyframe at 200 pixels. With ease-in-out, it speeds up and slows down twice, and even stops for a moment halfway. Want one easing over the whole motion? Then use only a start and an end keyframe, or use the Web Animations API. Its easing works over the whole animation, even with keyframes in between.
How precise are the CSS values on this page?
For each cubic-bezier(), we've searched for the four numbers that come closest to the real easing function. Most are less than 0.5% off. Only the sharpest easings, like ease in-out quintic, are about 1% off. Above 1.5%, linear() is used instead, like for ease in-out back and ease in-out circular.
The well-known values of easings.net, which the PostCSS plugin postcss-easings uses as well, work the same way, with a cubic-bezier() for each easing. They're a bit further off, though: up to 3.9%. For bounce and elastic easings they use @keyframes. Those are further off still, up to 19% for ease-out bounce. On average, the values here at Spicy Yoghurt are about three times as close.
All easing functions with graphs
Here's an overview of all 31 easing functions, from soft to sharp. Each one has a graph and the code, with tabs for the modern form with one argument (t), the classic form with four (t, b, c, d) by Robert Penner, and CSS. The code is plain JavaScript, so you can easily rewrite it for any other language, like C# or GDScript.
In the graphs, time runs from left to right, and the progress goes from bottom to top. The dots are placed at equal moments in time: where they're far apart, the object moves fast. Where they bunch up, it slows down.
Linear is no easing at all, just the same speed from start to end. Handy to compare the others with, and for things that never stop, like a wheel that spins.
function easeLinear(t) {
return t;
}function easeLinear (t, b, c, d) {
return c * t / d + b;
}linearSine easing is based on a sine wave. It's the softest easing of all, only a little different from linear. Use it when a motion should feel smooth, without anyone noticing the easing.
function easeInSine(t) {
return 1 - Math.cos(t * Math.PI / 2);
}function easeInSine (t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
}cubic-bezier(0.37, 0, 0.7, 0.53)function easeOutSine(t) {
return Math.sin(t * Math.PI / 2);
}function easeOutSine (t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
}cubic-bezier(0.29, 0.45, 0.62, 1)function easeInOutSine(t) {
return -(Math.cos(Math.PI * t) - 1) / 2;
}function easeInOutSine (t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
}cubic-bezier(0.36, 0, 0.64, 1)Quadratic easing raises the progress to the power of 2. Not too soft and not too strong, which makes it a good place to start.
function easeInQuad(t) {
return t * t;
}function easeInQuad (t, b, c, d) {
return c * (t /= d) * t + b;
}cubic-bezier(0.34, 0, 0.67, 0.34)function easeOutQuad(t) {
return 1 - (1 - t) * (1 - t);
}function easeOutQuad (t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
}cubic-bezier(0.33, 0.66, 0.66, 1)function easeInOutQuad(t) {
return t < 0.5
? 2 * t * t
: 1 - Math.pow(-2 * t + 2, 2) / 2;
}function easeInOutQuad (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}cubic-bezier(0.48, 0.04, 0.52, 0.96)Cubic easing uses the power of 3. It's a bit stronger than quadratic, and a favorite for buttons, menus and cameras.
function easeInCubic(t) {
return t * t * t;
}function easeInCubic (t, b, c, d) {
return c * (t /= d) * t * t + b;
}cubic-bezier(0.33, 0, 0.67, 0)function easeOutCubic(t) {
return 1 - Math.pow(1 - t, 3);
}function easeOutCubic (t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
}cubic-bezier(0.33, 1, 0.67, 1)function easeInOutCubic(t) {
return t < 0.5
? 4 * t * t * t
: 1 - Math.pow(-2 * t + 2, 3) / 2;
}function easeInOutCubic (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
}cubic-bezier(0.62, -0.04, 0.38, 1.04)Quartic easing uses the power of 4. With ease-in, most of the motion happens at the very end, and with ease-out right at the start.
function easeInQuart(t) {
return t * t * t * t;
}function easeInQuart (t, b, c, d) {
return c * (t /= d) * t * t * t + b;
}cubic-bezier(0.43, 0, 0.73, -0.07)function easeOutQuart(t) {
return 1 - Math.pow(1 - t, 4);
}function easeOutQuart (t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
}cubic-bezier(0.27, 1.07, 0.57, 1)function easeInOutQuart(t) {
return t < 0.5
? 8 * t * t * t * t
: 1 - Math.pow(-2 * t + 2, 4) / 2;
}function easeInOutQuart (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}cubic-bezier(0.71, -0.09, 0.29, 1.09)Quintic easing uses the power of 5. Even stronger than quartic, but still smooth.
function easeInQuint(t) {
return t * t * t * t * t;
}function easeInQuint (t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
}cubic-bezier(0.53, 0, 0.78, -0.09)function easeOutQuint(t) {
return 1 - Math.pow(1 - t, 5);
}function easeOutQuint (t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
}cubic-bezier(0.22, 1.11, 0.48, 0.99)function easeInOutQuint(t) {
return t < 0.5
? 16 * t * t * t * t * t
: 1 - Math.pow(-2 * t + 2, 5) / 2;
}function easeInOutQuint (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}cubic-bezier(0.77, -0.12, 0.23, 1.12)Exponential easing is based on a power of 2 that grows very fast. It's the sharpest of the basic easings. With ease-in, it starts long and gentle and ends with a quick burst, and with ease-out it's the other way around.
function easeInExpo(t) {
return t == 0 ? 0 : Math.pow(2, 10 * t - 10);
}function easeInExpo (t, b, c, d) {
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
}cubic-bezier(0.62, 0.02, 0.84, -0.08)function easeOutExpo(t) {
return t == 1 ? 1 : 1 - Math.pow(2, -10 * t);
}function easeOutExpo (t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
}cubic-bezier(0.15, 1.05, 0.36, 0.98)function easeInOutExpo(t) {
if (t == 0 || t == 1) {
return t;
}
return t < 0.5
? Math.pow(2, 20 * t - 10) / 2
: (2 - Math.pow(2, -20 * t + 10)) / 2;
}function easeInOutExpo (t, b, c, d) {
if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
}cubic-bezier(0.84, -0.12, 0.16, 1.12)Circular easing follows a quarter of a circle. With ease-in, it ends very suddenly. With ease-out, it starts very suddenly and slows down fast, a bit like hitting the brakes.
function easeInCirc(t) {
return 1 - Math.sqrt(1 - Math.pow(t, 2));
}function easeInCirc (t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
}cubic-bezier(0.55, 0, 1, 0.45)function easeOutCirc(t) {
return Math.sqrt(1 - Math.pow(t - 1, 2));
}function easeOutCirc (t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
}cubic-bezier(0, 0.56, 0.46, 1)function easeInOutCirc(t) {
return t < 0.5
? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2
: (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;
}function easeInOutCirc (t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
}linear(
0, 0.01 9.75%, 0.038 19.15%, 0.084 27.8%, 0.146 35.35%, 0.229 42%,
0.274 44.6%, 0.323 46.75%, 0.371 48.3%, 0.42 49.35%, 0.461 49.85%,
0.478 49.95%, 0.49 49.99%, 0.51 50.01%, 0.522 50.05%, 0.559 50.35%,
0.597 50.95%, 0.635 51.85%, 0.679 53.3%, 0.722 55.2%, 0.802 60.15%,
0.885 68.1%, 0.948 77.75%, 0.987 88.55%, 1
)Back easing goes a little past its target and comes back. With the number in the code, that's about 10%. Make the number bigger for a stronger effect.
function easeInBack(t) {
// How far it goes past the start, about 10%
const s = 1.70158;
return (s + 1) * t * t * t - s * t * t;
}function easeInBack (t, b, c, d, s = 1.70158) {
return c * (t /= d) * t * ((s + 1) * t - s) + b;
}cubic-bezier(0.32, 0, 0.67, -0.57)function easeOutBack(t) {
// How far it goes past the end, about 10%
const s = 1.70158;
return 1 + (s + 1) * Math.pow(t - 1, 3) + s * Math.pow(t - 1, 2);
}function easeOutBack (t, b, c, d, s = 1.70158) {
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
}cubic-bezier(0.33, 1.56, 0.66, 1)function easeInOutBack(t) {
const s = 1.70158 * 1.525;
return t < 0.5
? Math.pow(2 * t, 2) * ((s + 1) * 2 * t - s) / 2
: (Math.pow(2 * t - 2, 2) * ((s + 1) * (2 * t - 2) + s) + 2) / 2;
}function easeInOutBack (t, b, c, d, s = 1.70158) {
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
}linear(
0, -0.014 5.65%, -0.079 17%, -0.098 21.85%, -0.096 26.9%,
-0.066 31.45%, -0.032 34.2%, 0.015 36.85%, 0.074 39.4%, 0.145 41.85%,
0.226 44.15%, 0.319 46.4%, 0.415 48.4%, 0.635 52.6%, 0.787 56.2%,
0.863 58.4%, 0.929 60.7%, 0.983 63.05%, 1.027 65.5%, 1.061 68.1%,
1.084 70.8%, 1.097 73.65%, 1.1 76.75%, 1.083 82.3%, 1.012 94.7%, 1
)Elastic easing is a sine wave that gets smaller over time, like a spring that settles. It shoots past the target a few times, by up to 37%, so leave some room around the object.
function easeInElastic(t) {
if (t == 0 || t == 1) {
return t;
}
// A sine wave that grows bigger over time
let size = Math.pow(2, 10 * t - 10);
let wave = Math.sin((t * 10 - 10.75) * 2 * Math.PI / 3);
return -size * wave;
}function easeInElastic (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
}linear(
0, -0.006 27.75%, 0.016 42.45%, 0.004 46.75%, -0.042 54.3%,
-0.046 57.3%, -0.035 59.5%, -0.012 61.65%, 0.118 69.3%, 0.13 70.8%,
0.131 72.15%, 0.109 74.1%, 0.059 76%, -0.032 78.2%, -0.243 82.2%,
-0.315 83.8%, -0.364 85.5%, -0.373 86.3%, -0.371 87.05%, -0.346 88.2%,
-0.296 89.3%, -0.219 90.4%, -0.115 91.5%, 0 92.5%, 0.14 93.55%,
0.628 96.8%, 0.782 97.9%, 0.913 99%, 1
)function easeOutElastic(t) {
if (t == 0 || t == 1) {
return t;
}
// A sine wave that gets smaller over time
let size = Math.pow(2, -10 * t);
let wave = Math.sin((t * 10 - 0.75) * 2 * Math.PI / 3);
return size * wave + 1;
}function easeOutElastic (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
}linear(
0, 0.087 1%, 0.218 2.1%, 0.372 3.2%, 0.86 6.45%, 1 7.5%, 1.115 8.5%,
1.219 9.6%, 1.296 10.7%, 1.346 11.8%, 1.371 12.95%, 1.373 13.7%,
1.364 14.5%, 1.315 16.2%, 1.243 17.8%, 1.032 21.8%, 0.941 24%,
0.891 25.9%, 0.869 27.85%, 0.87 29.2%, 0.882 30.7%, 1.012 38.35%,
1.035 40.5%, 1.046 42.7%, 1.042 45.7%, 0.996 53.25%, 0.984 57.55%,
1.006 72.25%, 1
)function easeInOutElastic(t) {
if (t == 0 || t == 1) {
return t;
}
let wave = Math.sin((20 * t - 11.125) * 2 * Math.PI / 4.5);
return t < 0.5
? -Math.pow(2, 20 * t - 10) * wave / 2
: Math.pow(2, -20 * t + 10) * wave / 2 + 1;
}function easeInOutElastic (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d / 2) == 2) return b + c;
if (!p) p = d * (.3 * 1.5);
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
}linear(
0, -0.005 19.2%, 0.023 27.85%, 0.024 30.15%, 0.014 31.85%,
-0.005 33.5%, -0.109 39.05%, -0.118 40.2%, -0.114 41.2%,
-0.098 42.15%, -0.069 43.05%, -0.028 43.9%, 0.029 44.8%, 0.149 46.25%,
0.432 49.15%, 0.582 51%, 0.828 53.5%, 0.929 54.65%, 0.995 55.55%,
1.044 56.4%, 1.082 57.3%, 1.106 58.2%, 1.118 59.4%, 1.112 60.75%,
1.005 66.5%, 0.986 68.15%, 0.976 69.9%, 0.977 72.2%, 1.005 80.8%, 1
)Bounce easing works like a ball that you drop: it falls and bounces three times, each bounce lower than the one before. easeInBounce() and easeInOutBounce() use easeOutBounce(), so you'll need that one as well.
function easeInBounce(t) {
return 1 - easeOutBounce(1 - t);
}function easeInBounce (t, b, c, d) {
return c - easeOutBounce(d - t, 0, c, d) + b;
}linear(
0, 0.016 4.55%, 0 9.1%, 0.047 13.65%, 0.062 18.15%, 0.047 22.7%,
0 27.25%, 0.111 31.9%, 0.188 36.4%, 0.235 40.95%, 0.25 45.45%,
0.234 50%, 0.188 54.5%, 0.111 59%, 0.001 63.65%, 0.235 68.2%,
0.438 72.75%, 0.61 77.3%, 0.751 81.85%, 0.859 86.35%, 0.937 90.9%,
0.984 95.45%, 1
)function easeOutBounce(t) {
// A fall and three bounces, each one lower than the one before
const n = 7.5625;
const d = 2.75;
if (t < 1 / d) {
return n * t * t;
} else if (t < 2 / d) {
t -= 1.5 / d;
return n * t * t + 0.75;
} else if (t < 2.5 / d) {
t -= 2.25 / d;
return n * t * t + 0.9375;
} else {
t -= 2.625 / d;
return n * t * t + 0.984375;
}
}function easeOutBounce (t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
}linear(
0, 0.016 4.55%, 0.062 9.05%, 0.14 13.6%, 0.249 18.15%, 0.39 22.7%,
0.562 27.25%, 0.765 31.8%, 0.999 36.35%, 0.889 41%, 0.812 45.5%,
0.766 50%, 0.75 54.55%, 0.765 59.05%, 0.812 63.6%, 0.889 68.1%,
1 72.75%, 0.953 77.3%, 0.938 81.85%, 0.953 86.35%, 1 90.9%,
0.984 95.45%, 1
)function easeInOutBounce(t) {
return t < 0.5
? (1 - easeOutBounce(1 - 2 * t)) / 2
: (1 + easeOutBounce(2 * t - 1)) / 2;
}function easeInOutBounce (t, b, c, d) {
if (t < d / 2) return easeInBounce(t * 2, 0, c, d) * .5 + b;
return easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}linear(
0, 0.008 2.25%, 0 4.55%, 0.024 6.85%, 0.031 9.1%, 0.024 11.35%,
0 13.65%, 0.054 15.9%, 0.094 18.2%, 0.117 20.45%, 0.125 22.7%,
0.118 24.95%, 0.094 27.25%, 0.056 29.5%, 0 31.8%, 0.125 34.25%,
0.222 36.45%, 0.307 38.7%, 0.376 40.95%, 0.433 43.35%, 0.473 45.8%,
0.495 48.1%, 0.503 51.35%, 0.515 53.2%, 0.543 55.35%, 0.586 57.55%,
0.657 60.2%, 0.75 62.85%, 0.861 65.45%, 1 68.2%, 0.945 70.45%,
0.906 72.75%, 0.883 75%, 0.875 77.3%, 0.883 79.6%, 0.907 81.85%,
0.946 84.1%, 1 86.35%, 0.976 88.65%, 0.969 90.9%, 0.976 93.15%,
1 95.45%, 0.992 97.75%, 1
)Conclusion
Easing functions are a great way to spice up your animations. With the tool, you can find the right one for every motion and copy the code straight into your game or CSS animation. Try mixing different easings on the x- and y-axes, and you'll discover new ways to move from A to B!
If you have any questions, feel free to ask them in the comment section below. And if this tool helped you out, please share it with a friend who's making a game too.
Comments
Thanks! We've received your comment. We check every comment by hand before it appears, so this can take a few days.
No comments yet. Be the first to leave one!