Skip to content

Instantly share code, notes, and snippets.

@sketchpunk
Last active September 27, 2018 04:11
Show Gist options
  • Save sketchpunk/57de58005891c1e5e62ca3c6244f84a8 to your computer and use it in GitHub Desktop.
Save sketchpunk/57de58005891c1e5e62ca3c6244f84a8 to your computer and use it in GitHub Desktop.
Cubic Bezier Easing Curve
/*
Quick hacked together function to use a 4 point bezier curve as an easing function.
Some limitations :
- Curve CAN NOT intersect, each X value must be unqiue.
- First point must have an X = 0, y can be anything you want.
- Last point must have an X = 1, y can be anything you want.
t value for a bezier curve isn't really time, its more like the normalized length of the curve.
But we can use the x value as long as it exists between 0 and 1 as time. To do that, I'm performing
a simple binary searching looking for the target time (x). When x is found within ome margin of error, the t
value can then be used to get the corrisponding y value.
*/
function CBezierEase(target, x0,y0, x1,y1, x2,y2, x3,y3 ){
const TRIES = 30; // Max tries to find the best Y value
const MARGIN = 0.001; // How far from target to accept as correct value.
//TODO, Avoid doing binary search if near the beginning or the end.
//if(target <= 0.00001) // Target is Zero
//else if(target > 0.99999 ) //target is One
let a = 0, // Start of Range
b = 1, // End of Range
loop = 0,
t,tt, i, ii, x;
//Limit search by a few attempts.
while( loop++ < TRIES ){
t = (b - a) * 0.5 + a; // Get the Mid value between A and B
i = 1 - t; // Get the inverse of t
tt = t * t; // Save some time since t^2 is used more the once
ii = i * i; // Save for i
x = i*ii*x0 + 3*t*ii*x1 + 3*tt*i*x2 + t*tt*x3; // x value in the range's mid point
//If X is found by some margin of precision, good enough.
if( Math.abs(target - x) < MARGIN ) break; //console.log("found target at", t);
if(target > x) a = t; // Target is over, shift the start of the range to t
else if(target < x) b = t; // Target is under, shift the end of the range to t
}
return i*ii*y0 + 3*t*ii*y1 + 3*tt*i*y2 + t*tt*y3; //Return the best possible Y value found
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment