UNPKG

5.73 kBJavaScriptView Raw
1import {
2 cond,
3 lessThan,
4 multiply,
5 pow,
6 cos,
7 sqrt,
8 sub,
9 add,
10 divide,
11} from './base';
12import AnimatedBezier from './core/AnimatedBezier';
13
14/**
15 * The `Easing` module implements common easing functions. This module is used
16 * by [Animate.timing()](docs/animate.html#timing) to convey physically
17 * believable motion in animations.
18 *
19 * You can find a visualization of some common easing functions at
20 * http://easings.net/
21 *
22 * ### Predefined animations
23 *
24 * The `Easing` module provides several predefined animations through the
25 * following methods:
26 *
27 * - [`back`](docs/easing.html#back) provides a simple animation where the
28 * object goes slightly back before moving forward
29 * - [`bounce`](docs/easing.html#bounce) provides a bouncing animation
30 * - [`ease`](docs/easing.html#ease) provides a simple inertial animation
31 * - [`elastic`](docs/easing.html#elastic) provides a simple spring interaction
32 *
33 * ### Standard functions
34 *
35 * Three standard easing functions are provided:
36 *
37 * - [`linear`](docs/easing.html#linear)
38 * - [`quad`](docs/easing.html#quad)
39 * - [`cubic`](docs/easing.html#cubic)
40 *
41 * The [`poly`](docs/easing.html#poly) function can be used to implement
42 * quartic, quintic, and other higher power functions.
43 *
44 * ### Additional functions
45 *
46 * Additional mathematical functions are provided by the following methods:
47 *
48 * - [`bezier`](docs/easing.html#bezier) provides a cubic bezier curve
49 * - [`circle`](docs/easing.html#circle) provides a circular function
50 * - [`sin`](docs/easing.html#sin) provides a sinusoidal function
51 * - [`exp`](docs/easing.html#exp) provides an exponential function
52 *
53 * The following helpers are used to modify other easing functions.
54 *
55 * - [`in`](docs/easing.html#in) runs an easing function forwards
56 * - [`inOut`](docs/easing.html#inout) makes any easing function symmetrical
57 * - [`out`](docs/easing.html#out) runs an easing function backwards
58 */
59export default class Easing {
60 /**
61 * A linear function, `f(t) = t`. Position correlates to elapsed time one to
62 * one.
63 *
64 * http://cubic-bezier.com/#0,0,1,1
65 */
66 static linear(t) {
67 return t;
68 }
69
70 /**
71 * A simple inertial interaction, similar to an object slowly accelerating to
72 * speed.
73 *
74 * http://cubic-bezier.com/#.42,0,1,1
75 */
76 static ease(t) {
77 return new AnimatedBezier(t, 0.42, 0, 1, 1);
78 }
79
80 /**
81 * A quadratic function, `f(t) = t * t`. Position equals the square of elapsed
82 * time.
83 *
84 * http://easings.net/#easeInQuad
85 */
86 static quad(t) {
87 return multiply(t, t);
88 }
89
90 /**
91 * A cubic function, `f(t) = t * t * t`. Position equals the cube of elapsed
92 * time.
93 *
94 * http://easings.net/#easeInCubic
95 */
96 static cubic(t) {
97 return multiply(t, t, t);
98 }
99
100 /**
101 * A power function. Position is equal to the Nth power of elapsed time.
102 *
103 * n = 4: http://easings.net/#easeInQuart
104 * n = 5: http://easings.net/#easeInQuint
105 */
106 static poly(n) {
107 return t => pow(t, n);
108 }
109
110 /**
111 * A sinusoidal function.
112 *
113 * http://easings.net/#easeInSine
114 */
115 static sin(t) {
116 return sub(1, cos(multiply(t, Math.PI, 0.5)));
117 }
118
119 /**
120 * A circular function.
121 *
122 * http://easings.net/#easeInCirc
123 */
124 static circle(t) {
125 return sub(1, sqrt(sub(1, multiply(t, t))));
126 }
127
128 /**
129 * An exponential function.
130 *
131 * http://easings.net/#easeInExpo
132 */
133 static exp(t) {
134 return pow(2, multiply(10, sub(t, 1)));
135 }
136
137 /**
138 * A simple elastic interaction, similar to a spring oscillating back and
139 * forth.
140 *
141 * Default bounciness is 1, which overshoots a little bit once. 0 bounciness
142 * doesn't overshoot at all, and bounciness of N > 1 will overshoot about N
143 * times.
144 *
145 * http://easings.net/#easeInElastic
146 */
147 static elastic(bounciness = 1) {
148 const p = bounciness * Math.PI;
149 return t =>
150 sub(
151 1,
152 multiply(pow(cos(multiply(t, Math.PI, 0.5)), 3), cos(multiply(t, p)))
153 );
154 }
155
156 /**
157 * Use with `Animated.parallel()` to create a simple effect where the object
158 * animates back slightly as the animation starts.
159 *
160 * Wolfram Plot:
161 *
162 * - http://tiny.cc/back_default (s = 1.70158, default)
163 */
164 static back(s) {
165 if (s === undefined) {
166 s = 1.70158;
167 }
168 return t => multiply(t, t, sub(multiply(add(s, 1), t), s));
169 }
170
171 /**
172 * Provides a simple bouncing effect.
173 *
174 * http://easings.net/#easeInBounce
175 */
176 static bounce(t) {
177 const sq = v => multiply(7.5625, v, v);
178 return cond(
179 lessThan(t, 1 / 2.75),
180 sq(t),
181 cond(
182 lessThan(t, 2 / 2.75),
183 add(0.75, sq(sub(t, 1.5 / 2.75))),
184 cond(
185 lessThan(t, 2.5 / 2.76),
186 add(0.9375, sq(sub(t, 2.25 / 2.75))),
187 add(0.984375, sq(sub(t, 2.625 / 2.75)))
188 )
189 )
190 );
191 }
192
193 /**
194 * Provides a cubic bezier curve, equivalent to CSS Transitions'
195 * `transition-timing-function`.
196 *
197 * A useful tool to visualize cubic bezier curves can be found at
198 * http://cubic-bezier.com/
199 */
200 static bezier(x1, y1, x2, y2) {
201 return t => new AnimatedBezier(t, x1, y1, x2, y2);
202 }
203
204 /**
205 * Runs an easing function forwards.
206 */
207 static in(easing) {
208 return easing;
209 }
210
211 /**
212 * Runs an easing function backwards.
213 */
214 static out(easing) {
215 return t => sub(1, easing(sub(1, t)));
216 }
217
218 /**
219 * Makes any easing function symmetrical. The easing function will run
220 * forwards for half of the duration, then backwards for the rest of the
221 * duration.
222 */
223 static inOut(easing) {
224 return t =>
225 cond(
226 lessThan(t, 0.5),
227 divide(easing(multiply(t, 2)), 2),
228 sub(1, divide(easing(multiply(sub(1, t), 2)), 2))
229 );
230 }
231}