[RN] improve elastic easing
Summary: 1) Makes params more intuitive (only one now, bounciness, which maps intuitively to number of oscillations). 2) Satisfies boundary conditions (f(0) = 0, f(1) = 1) so animation actually goes where you tell it (before it would finish at a random location depending on the input params). 3) Simple test to verify boundary conditions.
This commit is contained in:
parent
d87480e9ac
commit
9ad2c322c0
|
@ -59,21 +59,22 @@ class Easing {
|
||||||
return Math.pow(2, 10 * (t - 1));
|
return Math.pow(2, 10 * (t - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static elastic(a: number, p: number): (t: number) => number {
|
/**
|
||||||
var tau = Math.PI * 2;
|
* A simple elastic interaction, similar to a spring. Default bounciness
|
||||||
// flow isn't smart enough to figure out that s is always assigned to a
|
* is 1, which overshoots a little bit once. 0 bounciness doesn't overshoot
|
||||||
// number before being used in the returned function
|
* at all, and bounciness of N > 1 will overshoot about N times.
|
||||||
var s: any;
|
*
|
||||||
if (arguments.length < 2) {
|
* Wolfram Plots:
|
||||||
p = 0.45;
|
*
|
||||||
|
* http://tiny.cc/elastic_b_1 (default bounciness = 1)
|
||||||
|
* http://tiny.cc/elastic_b_3 (bounciness = 3)
|
||||||
|
*/
|
||||||
|
static elastic(bounciness: number): (t: number) => number {
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
bounciness = 1;
|
||||||
}
|
}
|
||||||
if (arguments.length) {
|
var p = bounciness * Math.PI;
|
||||||
s = p / tau * Math.asin(1 / a);
|
return (t) => 1 - Math.pow(Math.cos(t * Math.PI / 2), 3) * Math.cos(t * p);
|
||||||
} else {
|
|
||||||
a = 1;
|
|
||||||
s = p / 4;
|
|
||||||
}
|
|
||||||
return (t) => 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * tau / p);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static back(s: number): (t: number) => number {
|
static back(s: number): (t: number) => number {
|
||||||
|
|
|
@ -71,6 +71,14 @@ describe('Easing', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should satisfy boundary conditions with elastic', () => {
|
||||||
|
for (var b = 0; b < 4; b += 0.3) {
|
||||||
|
var easing = Easing.elastic(b);
|
||||||
|
expect(easing(0)).toBe(0);
|
||||||
|
expect(easing(1)).toBe(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function sampleEasingFunction(easing) {
|
function sampleEasingFunction(easing) {
|
||||||
var DURATION = 300;
|
var DURATION = 300;
|
||||||
var tickCount = Math.round(DURATION * 60 / 1000);
|
var tickCount = Math.round(DURATION * 60 / 1000);
|
||||||
|
|
Loading…
Reference in New Issue