Last active
September 27, 2018 04:11
-
-
Save sketchpunk/57de58005891c1e5e62ca3c6244f84a8 to your computer and use it in GitHub Desktop.
Cubic Bezier Easing Curve
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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