Comments (2)
I tried writing a test and found that bezier-easing is indeed "faster", using bezier.css.methond()
is faster, but using bezier(a,b,c,d)
directly is slower than jQuery.easing.method()
, is this a browser caching factor ?
I'm not sure if my test like this is actually possible, am I missing some parameters? I hope someone can help me to answer, the following is the specific code and test results.
Test Code
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/jquery.easing.min.js"></script>
<script>
$(function(){
var start;
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ jQuery.easing.linear(i) };
console.log('jQuery.easing.linear ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ jQuery.easing.swing(i) };
console.log('jQuery.easing.swing ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ jQuery.easing.easeOutCirc(i) };
console.log('jQuery.easing.easeOutCirc ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier.css.linear() };
console.log('bezier-easing linear ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier( 0.00, 0.00, 1.00, 1.00) };
console.log('bezier-easing linear ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier.css.swing() };
console.log('bezier-easing swing ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier( 0.02, 0.01, 0.47, 1.00) };
console.log('bezier-easing swing ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier.css.easeOutCirc() };
console.log('bezier-easing easeOutCirc ' + (Date.now() - start));
start = Date.now();
for(var i=0,l=1000000; i<l; i++){ bezier( 0.00, 0.55, 0.45, 1.00) };
console.log('bezier-easing easeOutCirc ' + (Date.now() - start));
// Here are the test results
// jQuery.easing.linear 19
// jQuery.easing.swing 55
// jQuery.easing.easeOutCirc 25
// bezier-easing linear 4
// bezier-easing linear 5
// bezier-easing swing 18
// bezier-easing swing 99
// bezier-easing easeOutCirc 12
// bezier-easing easeOutCirc 90
});
/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*/
var bezier = null;
(function(){
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === 'function';
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C (aA1) { return 3.0 * aA1; }
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
function binarySubdivide (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function LinearEasing (x) {
return x;
}
bezier = function(mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
}
if (mX1 === mY1 && mX2 === mY2) {
return LinearEasing;
}
// Precompute samples table
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
function getTForX (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return function BezierEasing (x) {
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0 || x === 1) {
return x;
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
// CSS mapping
bezier.css = {
"ease": bezier( 0.25, 0.10, 0.25, 1.00),
"swing": bezier( 0.02, 0.01, 0.47, 1.00),
"linear": bezier( 0.00, 0.00, 1.00, 1.00),
"ease-in": bezier( 0.42, 0.00, 1.00, 1.00),
"ease-out": bezier( 0.00, 0.00, 0.58, 1.00),
"ease-in-out": bezier( 0.42, 0.00, 0.58, 1.00),
"easeInSine": bezier( 0.12, 0.00, 0.39, 0.00),
"easeOutSine": bezier( 0.61, 1.00, 0.88, 1.00),
"easeInOutSine": bezier( 0.37, 0.00, 0.63, 1.00),
"easeInQuad": bezier( 0.11, 0.00, 0.50, 0.00),
"easeOutQuad": bezier( 0.50, 1.00, 0.89, 1.00),
"easeInOutQuad": bezier( 0.45, 0.00, 0.55, 1.00),
"easeInCubic": bezier( 0.32, 0.00, 0.67, 0.00),
"easeOutCubic": bezier( 0.33, 1.00, 0.68, 1.00),
"easeInOutCubic": bezier( 0.65, 0.00, 0.35, 1.00),
"easeInQuart": bezier( 0.50, 0.00, 0.75, 0.00),
"easeOutQuart": bezier( 0.25, 1.00, 0.50, 1.00),
"easeInOutQuart": bezier( 0.76, 0.00, 0.24, 1.00),
"easeInQuint": bezier( 0.64, 0.00, 0.78, 0.00),
"easeOutQuint": bezier( 0.22, 1.00, 0.36, 1.00),
"easeInOutQuint": bezier( 0.83, 0.00, 0.17, 1.00),
"easeInExpo": bezier( 0.70, 0.00, 0.84, 0.00),
"easeOutExpo": bezier( 0.16, 1.00, 0.30, 1.00),
"easeInOutExpo": bezier( 0.87, 0.00, 0.13, 1.00),
"easeInCirc": bezier( 0.55, 0.00, 1.00, 0.45),
"easeOutCirc": bezier( 0.00, 0.55, 0.45, 1.00),
"easeInOutCirc": bezier( 0.85, 0.00, 0.15, 1.00),
"easeInBack": bezier( 0.36, 0.00, 0.66, -0.56),
"easeOutBack": bezier( 0.34, 1.56, 0.64, 1.00),
"easeInOutBack": bezier( 0.68, -0.60, 0.32, 1.60),
// "easeInElastic": it can't use bezier() to come true,
// "easeOutElastic": it can't use bezier() to come true,
// "easeInOutElastic": it can't use bezier() to come true,
// "easeInBounce": it can't use bezier() to come true,
// "easeOutBounce": it can't use bezier() to come true,
// "easeInOutBounce": it can't use bezier() to come true,
};
})();
</script>
from bezier-easing.
easing functions that are directly written in a simple math formula without using bezier lookup are always going to be faster.
see article https://greweb.me/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation
bezier implementation is a generalization of all these curves tho, so there is the freedom to express many kind of easing functions, feature that come with the price of being a bit less performant, but it's still very performant and depending on your usecase may not really matter.
hope this answers it.
from bezier-easing.
Related Issues (20)
- Example link in readme can't be found HOT 1
- Version 1.0 breaks with angular/bower HOT 2
- `var global = this;` causes break while working with es6 `import` HOT 1
- New version, problem with GSAP HOT 4
- index.js:54 Uncaught ReferenceError: module is not defined HOT 2
- Looking to make complex curves HOT 11
- Curve not working on Raspberry Pi in QML HOT 3
- BezierEasing() should start with lower case letter HOT 1
- Breaking compilation whitespace index.js:140 HOT 5
- Add typescript definitions HOT 1
- Is this intentional behavior? HOT 5
- Typings file not found in latest npm install HOT 4
- TimeFunction link in README.md is broken HOT 1
- bezier library HOT 1
- if I want to get x by y? HOT 3
- Very slow on babel+rollup ES6/ES7 compilation HOT 8
- 'bezier-easing'. CommonJS or AMD dependencies can cause optimization bailouts. HOT 1
- How to use with svg path's bezier curve, degined by 6 points? HOT 1
- Links in README are broken HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bezier-easing.