Skip to content

Instantly share code, notes, and snippets.

@w3Serif
Forked from gre/easing.js
Last active December 19, 2019 06:32
Show Gist options
  • Select an option

  • Save w3Serif/cb0e644204836406e9ee3f0a1e4845d0 to your computer and use it in GitHub Desktop.

Select an option

Save w3Serif/cb0e644204836406e9ee3f0a1e4845d0 to your computer and use it in GitHub Desktop.
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: function (t) { return t },
// accelerating from zero velocity
easeInQuad: function (t) { return t*t },
// decelerating to zero velocity
easeOutQuad: function (t) { return t*(2-t) },
// acceleration until halfway, then deceleration
easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t },
// accelerating from zero velocity
easeInCubic: function (t) { return t*t*t },
// decelerating to zero velocity
easeOutCubic: function (t) { return (--t)*t*t+1 },
// acceleration until halfway, then deceleration
easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 },
// accelerating from zero velocity
easeInQuart: function (t) { return t*t*t*t },
// decelerating to zero velocity
easeOutQuart: function (t) { return 1-(--t)*t*t*t },
// acceleration until halfway, then deceleration
easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
// accelerating from zero velocity
easeInQuint: function (t) { return t*t*t*t*t },
// decelerating to zero velocity
easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
// acceleration until halfway, then deceleration
easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t }
}
/* V2 Preffered */
/*
* Easing
* Taken from: https://kodhus.com/easings/
*/
const Easing = {
/*
* Usage:
* t: current time
* b: starting position
* c: amount of change (end - start)
* d: total animation time
*
* Example:
* let frameRate = 60/1000
* easing(currentTime, start, end - start, duration * frameRate);
*/
linear: function(t, b, c, d) {
return c*t/d + b;
},
quad: {
in: function(t, b, c, d) {
t /= d;
return c*t*t + b;
},
out: function (t, b, c, d) {
t /= d;
return -c * t*(t-2) + b;
},
inout: function(t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t + b;
t--;
return -c/2 * (t*(t-2) - 1) + b;
}
},
cubic: {
in: function (t, b, c, d) {
return c*(t/=d)*t*t + b;
},
out: function (t, b, c, d) {
return c*((t=t/d-1)*t*t + 1) + b;
},
inout: function (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;
}
},
quart: {
in: function (t, b, c, d) {
return c*(t/=d)*t*t*t + b;
},
out: function (t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
inout: function (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;
}
},
quint: {
in: function (t, b, c, d) {
return c*(t/=d)*t*t*t*t + b;
},
out: function (t, b, c, d) {
return c*((t=t/d-1)*t*t*t*t + 1) + b;
},
inout: function (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;
}
},
sine: {
in: function (t, b, c, d) {
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
},
out: function (t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b;
},
inout: function (t, b, c, d) {
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
}
},
expo: {
in: function (t, b, c, d) {
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
},
out: function (t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
},
inout: function (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;
}
},
circ: {
in: function (t, b, c, d) {
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
},
out: function (t, b, c, d) {
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
},
inout: function (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;
}
},
elastic: {
in: function (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;
},
out: function (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;
},
inout: function (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;
}
},
back: {
in: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c*(t/=d)*t*((s+1)*t - s) + b;
},
out: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
inout: function (t, b, c, d, s) {
if (s == undefined) 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;
}
},
bounce: {
in: function(t, b, c, d) {
console.log('this', Easing);
return c - Easing.bounce.out(d-t, 0, c, d) + b;
},
out: function(t, b, c, d, s) {
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;
}
},
inout: function(t, b, c, d) {
if (t < d/2) return Easing.bounce.in(t*2, 0, c, d) * .5 + b;
return Easing.bounce.out(t*2-d, 0, c, d) * .5 + c*.5 + b;
},
}
};
const timingFunc = function(type, curStep, startPosition, amountOfChange, totalSteps){
function getTData() {
const list = type.split('-');
const isShortFunc = list.length === 2;
const easingFunc = isShortFunc ? Easing[list[1]] : Easing[list[2]][list[1]];
return { easingFunc, isShortFunc, list }
}
timingFunc.caches = timingFunc.caches || {};
timingFunc.caches[type] = timingFunc.caches[type] || getTData();
const f = timingFunc.caches[type];
startPosition = f.isShortFunc ? 0 :
f.list[1] === 'in' ? startPosition :
0;
return f.easingFunc(curStep, startPosition, amountOfChange, totalSteps);
};
export const getTFuncList = () => {
let entries = Object.entries(Easing);
let itemsList = [];
entries.forEach((i) => {
let item = `ease-`;
if (isObject(i[1])) {
let it = Object.keys(i[1]).map(s => item + s + '-' + i[0]);
itemsList.push(it);
}
else {
itemsList.push(item+i[0])
}
});
return itemsList;
};
////////////////////////////////////////
// Timing function. Usage example: ///
///////////////////////////////////////
/*
const frames = 10;
let dist = 100;
let curpos = 0;
console.log(`from 0 to 100`,'---------------------------------');
for (let i=0; i <= frames; i++) {
let out = timingFunc('ease-out-cubic', i, curpos, dist, frames);
let ins = timingFunc('ease-in-cubic', i, curpos, dist, frames);
let inout = timingFunc('ease-inout-cubic', i, curpos, dist, frames);
console.log(i,'out',out, '\n\tin', ins, '\n\tinout', inout);
}
console.log('\n\n---------------------------------');
console.log('100 to 0---------------------------------');
for (let i=0; i <= frames; i++) {
let out = timingFunc('ease-out-cubic', i, curpos, dist, frames);
let ins = timingFunc('ease-in-cubic', i, curpos, dist, frames);
let inout = timingFunc('ease-inout-cubic', i, curpos, dist, frames);
console.log(i,'out', dist-out, '\n\tin', dist-ins, '\n\tinout', dist-inout);
}
console.log('50 to 100---------------------------------');
curpos = 0;
dist = 50; // 100 - 50
for (let i=0; i <= frames; i++) {
let out = timingFunc('ease-out-cubic', i, curpos, dist, frames);
console.log(i,'out', dist+out,);
}
*/
export default timingFunc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment