diff options
Diffstat (limited to 'src/_easing.scss')
-rw-r--r-- | src/_easing.scss | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/src/_easing.scss b/src/_easing.scss new file mode 100644 index 0000000..c41635b --- /dev/null +++ b/src/_easing.scss | |||
@@ -0,0 +1,483 @@ | |||
1 | //// | ||
2 | /// Easing. | ||
3 | /// | ||
4 | /// A collection of easing functions which are commonly used for animations. | ||
5 | /// This code is based on https://github.com/gre/bezier-easing. | ||
6 | /// | ||
7 | /// @group Easing | ||
8 | /// | ||
9 | /// @access public | ||
10 | //// | ||
11 | |||
12 | /// | ||
13 | /// @access private | ||
14 | /// | ||
15 | $iro-cubic-bezier-sample-pool: (); | ||
16 | |||
17 | /// | ||
18 | /// Sample pool size for cubic bezier calculations. | ||
19 | /// | ||
20 | $iro-cubic-bezier-sample-pool-size: 10 !default; | ||
21 | |||
22 | /// | ||
23 | /// Minimum slope required to use the Newton-Raphson method for cubic bezier calculations. | ||
24 | /// | ||
25 | $iro-cubic-bezier-newton-min-slope: 0.001 !default; | ||
26 | |||
27 | /// | ||
28 | /// Number of iterations of the Newton-Raphson method. | ||
29 | /// | ||
30 | $iro-cubic-bezier-newton-iters: 4 !default; | ||
31 | |||
32 | /// | ||
33 | /// Precision of the subdivision method for cubic bezier calculations. | ||
34 | /// | ||
35 | $iro-cubic-bezier-subdiv-precision: 0.0000001 !default; | ||
36 | |||
37 | /// | ||
38 | /// Maximum iterations of the subdivision method for cubic bezier calculations. | ||
39 | /// | ||
40 | $iro-cubic-bezier-subdiv-max-iters: 10 !default; | ||
41 | |||
42 | /// | ||
43 | /// A cubic bezier function identical to the CSS cubic-bezier function. | ||
44 | /// | ||
45 | /// @param {number} $x1 - X of first point | ||
46 | /// @param {number} $y1 - Y of first point | ||
47 | /// @param {number} $x2 - X of second point | ||
48 | /// @param {number} $y2 - Y of second point | ||
49 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
50 | /// | ||
51 | /// @return {number} | ||
52 | /// | ||
53 | @function iro-cubic-bezier($x1, $y1, $x2, $y2, $x) { | ||
54 | // | ||
55 | // Cover simple cases | ||
56 | // | ||
57 | |||
58 | @if ($x1 == $y1) and ($x2 == $y2) { | ||
59 | @return $x; | ||
60 | } | ||
61 | @if $x == 0 { | ||
62 | @return 0; | ||
63 | } | ||
64 | @if $x == 1 { | ||
65 | @return 1; | ||
66 | } | ||
67 | |||
68 | // | ||
69 | // Generate samples | ||
70 | // | ||
71 | |||
72 | $sample-pool-key: $x1 + '_' + $x2; | ||
73 | |||
74 | @if not map-has-key($iro-cubic-bezier-sample-pool, $sample-pool-key) { | ||
75 | $samples: (); | ||
76 | |||
77 | @for $i from 0 through $iro-cubic-bezier-sample-pool-size { | ||
78 | $samples: append($samples, iro-cubic-bezier-func($x1, $x2, $i / $iro-cubic-bezier-sample-pool-size)); | ||
79 | } | ||
80 | |||
81 | $iro-cubic-bezier-sample-pool: map-merge($iro-cubic-bezier-sample-pool, ($sample-pool-key: $samples)) !global; | ||
82 | } | ||
83 | |||
84 | // | ||
85 | // Calculate cubic bezier | ||
86 | // | ||
87 | |||
88 | @return iro-cubic-bezier-func($y1, $y2, iro-cubic-bezier-t-for-x($x1, $x2, $x)); | ||
89 | } | ||
90 | |||
91 | /// | ||
92 | /// @access private | ||
93 | /// | ||
94 | @function iro-cubic-bezier-func-a($p1, $p2) { | ||
95 | @return 1 - 3 * $p2 + 3 * $p1; | ||
96 | } | ||
97 | |||
98 | /// | ||
99 | /// @access private | ||
100 | /// | ||
101 | @function iro-cubic-bezier-func-b($p1, $p2) { | ||
102 | @return 3 * $p2 - 6 * $p1; | ||
103 | } | ||
104 | |||
105 | /// | ||
106 | /// @access private | ||
107 | /// | ||
108 | @function iro-cubic-bezier-func-c($p1) { | ||
109 | @return 3 * $p1; | ||
110 | } | ||
111 | |||
112 | /// | ||
113 | /// One-dimensional cubic bezier function. | ||
114 | /// | ||
115 | /// @access private | ||
116 | /// | ||
117 | @function iro-cubic-bezier-func($p1, $p2, $t) { | ||
118 | @return ((iro-cubic-bezier-func-a($p1, $p2) * $t + iro-cubic-bezier-func-b($p1, $p2)) * $t + iro-cubic-bezier-func-c($p1)) * $t; | ||
119 | } | ||
120 | |||
121 | /// | ||
122 | /// Derivative of the one-dimensional cubic bezier function. | ||
123 | /// | ||
124 | /// @access private | ||
125 | /// | ||
126 | @function iro-cubic-bezier-func-slope($p1, $p2, $t) { | ||
127 | @return 3 * iro-cubic-bezier-func-a($p1, $p2) * $t * $t + 2 * iro-cubic-bezier-func-b($p1, $p2) * $t + iro-cubic-bezier-func-c($p1); | ||
128 | } | ||
129 | |||
130 | /// | ||
131 | /// Newton-Raphson method to calculate the t parameter for a given x parameter. | ||
132 | /// | ||
133 | /// @access private | ||
134 | /// | ||
135 | @function iro-cubic-bezier-newton-raphson($x1, $x2, $x, $t) { | ||
136 | @for $i from 1 through $iro-cubic-bezier-newton-iters { | ||
137 | $cur-slope: iro-cubic-bezier-func-slope($x1, $x2, $t); | ||
138 | |||
139 | @if $cur-slope == 0 { | ||
140 | @return $t; | ||
141 | } | ||
142 | |||
143 | $cur-x: iro-cubic-bezier-func($x1, $x2, $t) - $x; | ||
144 | $t: $t - $cur-x / $cur-slope; | ||
145 | } | ||
146 | |||
147 | @return $t; | ||
148 | } | ||
149 | |||
150 | /// | ||
151 | /// Subdivision method to calculate the t parameter for a given x parameter. | ||
152 | /// | ||
153 | /// @access private | ||
154 | /// | ||
155 | @function iro-cubic-bezier-binary-subdivide($x1, $x2, $x, $a, $b) { | ||
156 | $cur-x: 0; | ||
157 | $cur-t: 0; | ||
158 | $i: 0; | ||
159 | |||
160 | @while $i < $iro-cubic-bezier-subdiv-max-iters { | ||
161 | $cur-t: $a + ($b - $a) / 2; | ||
162 | $cur-x: iro-cubic-bezier-func($x1, $x2, $cur-t) - $x; | ||
163 | |||
164 | @if $cur-x > 0 { | ||
165 | $b: $cur-t; | ||
166 | } @else { | ||
167 | $a: $cur-t; | ||
168 | } | ||
169 | |||
170 | @if abs($cur-x) < $iro-cubic-bezier-subdiv-precision { | ||
171 | @return $cur-t; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | @return $cur-t; | ||
176 | } | ||
177 | |||
178 | /// | ||
179 | /// Calculate the t parameter for a given x parameter. | ||
180 | /// | ||
181 | /// @access private | ||
182 | /// | ||
183 | @function iro-cubic-bezier-t-for-x($x1, $x2, $x) { | ||
184 | $sample-pool-key: $x1 + '_' + $x2; | ||
185 | $samples: map-get($iro-cubic-bezier-sample-pool, $sample-pool-key); | ||
186 | |||
187 | $intv-start: 0; | ||
188 | $cur-sample: 1; | ||
189 | $last-sample: $iro-cubic-bezier-sample-pool-size; | ||
190 | |||
191 | @while ($cur-sample != $last-sample) and (nth($samples, $cur-sample) <= $x) { | ||
192 | $intv-start: $intv-start + (1 / $iro-cubic-bezier-sample-pool-size); | ||
193 | $cur-sample: $cur-sample + 1; | ||
194 | } | ||
195 | $cur-sample: $cur-sample - 1; | ||
196 | |||
197 | $dist: ($x - nth($samples, $cur-sample)) / (nth($samples, $cur-sample + 1) - nth($samples, $cur-sample)); | ||
198 | $guess-t: $intv-start + $dist / $iro-cubic-bezier-sample-pool-size; | ||
199 | |||
200 | $init-slope: iro-cubic-bezier-func-slope($x1, $x2, $guess-t); | ||
201 | @if $init-slope >= $iro-cubic-bezier-newton-min-slope { | ||
202 | @return iro-cubic-bezier-newton-raphson($x1, $x2, $x, $guess-t); | ||
203 | } @else if $init-slope == 0 { | ||
204 | @return $guess-t; | ||
205 | } @else { | ||
206 | @return iro-cubic-bezier-binary-subdivide($x1, $x2, $x, $intv-start, $intv-start + 1 / $iro-cubic-bezier-sample-pool-size); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /// | ||
211 | /// Sinusoidal easing function (in direction). | ||
212 | /// | ||
213 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
214 | /// | ||
215 | /// @return {number} | ||
216 | /// | ||
217 | @function iro-ease($x) { | ||
218 | @return iro-cubic-bezier(0.25, 0.1, 0.25, 1, $x); | ||
219 | } | ||
220 | |||
221 | /// | ||
222 | /// Sinusoidal easing function (in direction). | ||
223 | /// | ||
224 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
225 | /// | ||
226 | /// @return {number} | ||
227 | /// | ||
228 | @function iro-ease-in($x) { | ||
229 | @return iro-cubic-bezier(0.42, 0, 1, 1, $x); | ||
230 | } | ||
231 | |||
232 | /// | ||
233 | /// Sinusoidal easing function (out direction). | ||
234 | /// | ||
235 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
236 | /// | ||
237 | /// @return {number} | ||
238 | /// | ||
239 | @function iro-ease-out($x) { | ||
240 | @return iro-cubic-bezier(0, 0, 0.58, 1, $x); | ||
241 | } | ||
242 | |||
243 | /// | ||
244 | /// Sinusoidal easing function (in-out direction). | ||
245 | /// | ||
246 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
247 | /// | ||
248 | /// @return {number} | ||
249 | /// | ||
250 | @function iro-ease-in-out($x) { | ||
251 | @return iro-cubic-bezier(0.42, 0, 0.58, 1, $x); | ||
252 | } | ||
253 | |||
254 | /// | ||
255 | /// Sinusoidal easing function (in direction). | ||
256 | /// | ||
257 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
258 | /// | ||
259 | /// @return {number} | ||
260 | /// | ||
261 | @function iro-ease-in-sine($x) { | ||
262 | @return iro-cubic-bezier(0.47, 0, 0.745, 0.715, $x); | ||
263 | } | ||
264 | |||
265 | /// | ||
266 | /// Sinusoidal easing function (out direction). | ||
267 | /// | ||
268 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
269 | /// | ||
270 | /// @return {number} | ||
271 | /// | ||
272 | @function iro-ease-out-sine($x) { | ||
273 | @return iro-cubic-bezier(0.39, 0.575, 0.565, 1, $x); | ||
274 | } | ||
275 | |||
276 | /// | ||
277 | /// Sinusoidal easing function (in-out direction). | ||
278 | /// | ||
279 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
280 | /// | ||
281 | /// @return {number} | ||
282 | /// | ||
283 | @function iro-ease-in-out-sine($x) { | ||
284 | @return iro-cubic-bezier(0.445, 0.05, 0.55, 0.95, $x); | ||
285 | } | ||
286 | |||
287 | /// | ||
288 | /// Quadratic easing function (in direction). | ||
289 | /// | ||
290 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
291 | /// | ||
292 | /// @return {number} | ||
293 | /// | ||
294 | @function iro-ease-in-quad($x) { | ||
295 | @return iro-cubic-bezier(0.55, 0.085, 0.68, 0.53, $x); | ||
296 | } | ||
297 | |||
298 | /// | ||
299 | /// Quadratic easing function (out direction). | ||
300 | /// | ||
301 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
302 | /// | ||
303 | /// @return {number} | ||
304 | /// | ||
305 | @function iro-ease-out-quad($x) { | ||
306 | @return iro-cubic-bezier(0.25, 0.46, 0.45, 0.94, $x); | ||
307 | } | ||
308 | |||
309 | /// | ||
310 | /// Quadratic easing function (in-out direction). | ||
311 | /// | ||
312 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
313 | /// | ||
314 | /// @return {number} | ||
315 | /// | ||
316 | @function iro-ease-in-out-quad($x) { | ||
317 | @return iro-cubic-bezier(0.455, 0.03, 0.515, 0.955, $x); | ||
318 | } | ||
319 | |||
320 | /// | ||
321 | /// Cubic easing function (in direction). | ||
322 | /// | ||
323 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
324 | /// | ||
325 | /// @return {number} | ||
326 | /// | ||
327 | @function iro-ease-in-cubic($x) { | ||
328 | @return iro-cubic-bezier(0.55, 0.055, 0.675, 0.19, $x); | ||
329 | } | ||
330 | |||
331 | /// | ||
332 | /// Cubic easing function (out direction). | ||
333 | /// | ||
334 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
335 | /// | ||
336 | /// @return {number} | ||
337 | /// | ||
338 | @function iro-ease-out-cubic($x) { | ||
339 | @return iro-cubic-bezier(0.215, 0.61, 0.355, 1, $x); | ||
340 | } | ||
341 | |||
342 | /// | ||
343 | /// Cubic easing function (in-out direction). | ||
344 | /// | ||
345 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
346 | /// | ||
347 | /// @return {number} | ||
348 | /// | ||
349 | @function iro-ease-in-out-cubic($x) { | ||
350 | @return iro-cubic-bezier(0.645, 0.045, 0.355, 1, $x); | ||
351 | } | ||
352 | |||
353 | /// | ||
354 | /// Quart easing function (in direction). | ||
355 | /// | ||
356 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
357 | /// | ||
358 | /// @return {number} | ||
359 | /// | ||
360 | @function iro-ease-in-quart($x) { | ||
361 | @return iro-cubic-bezier(0.895, 0.03, 0.685, 0.22, $x); | ||
362 | } | ||
363 | |||
364 | /// | ||
365 | /// Quart easing function (out direction). | ||
366 | /// | ||
367 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
368 | /// | ||
369 | /// @return {number} | ||
370 | /// | ||
371 | @function iro-ease-out-quart($x) { | ||
372 | @return iro-cubic-bezier(0.165, 0.84, 0.44, 1, $x); | ||
373 | } | ||
374 | |||
375 | /// | ||
376 | /// Quart easing function (in-out direction). | ||
377 | /// | ||
378 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
379 | /// | ||
380 | /// @return {number} | ||
381 | /// | ||
382 | @function iro-ease-in-out-quart($x) { | ||
383 | @return iro-cubic-bezier(0.77, 0, 0.175, 1, $x); | ||
384 | } | ||
385 | |||
386 | /// | ||
387 | /// Quint easing function (in direction). | ||
388 | /// | ||
389 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
390 | /// | ||
391 | /// @return {number} | ||
392 | /// | ||
393 | @function iro-ease-in-quint($x) { | ||
394 | @return iro-cubic-bezier(0.755, 0.05, 0.855, 0.06, $x); | ||
395 | } | ||
396 | |||
397 | /// | ||
398 | /// Quint easing function (out direction). | ||
399 | /// | ||
400 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
401 | /// | ||
402 | /// @return {number} | ||
403 | /// | ||
404 | @function iro-ease-out-quint($x) { | ||
405 | @return iro-cubic-bezier(0.23, 1, 0.32, 1, $x); | ||
406 | } | ||
407 | |||
408 | /// | ||
409 | /// Quint easing function (in-out direction). | ||
410 | /// | ||
411 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
412 | /// | ||
413 | /// @return {number} | ||
414 | /// | ||
415 | @function iro-ease-in-out-quint($x) { | ||
416 | @return iro-cubic-bezier(0.86, 0, 0.07, 1, $x); | ||
417 | } | ||
418 | |||
419 | /// | ||
420 | /// Exponential easing function (in direction). | ||
421 | /// | ||
422 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
423 | /// | ||
424 | /// @return {number} | ||
425 | /// | ||
426 | @function iro-ease-in-expo($x) { | ||
427 | @return iro-cubic-bezier(0.95, 0.05, 0.795, 0.035, $x); | ||
428 | } | ||
429 | |||
430 | /// | ||
431 | /// Exponential easing function (out direction). | ||
432 | /// | ||
433 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
434 | /// | ||
435 | /// @return {number} | ||
436 | /// | ||
437 | @function iro-ease-out-expo($x) { | ||
438 | @return iro-cubic-bezier(0.19, 1, 0.22, 1, $x); | ||
439 | } | ||
440 | |||
441 | /// | ||
442 | /// Exponential easing function (in-out direction). | ||
443 | /// | ||
444 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
445 | /// | ||
446 | /// @return {number} | ||
447 | /// | ||
448 | @function iro-ease-in-out-expo($x) { | ||
449 | @return iro-cubic-bezier(1, 0, 0, 1, $x); | ||
450 | } | ||
451 | |||
452 | /// | ||
453 | /// Circular easing function (in direction). | ||
454 | /// | ||
455 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
456 | /// | ||
457 | /// @return {number} | ||
458 | /// | ||
459 | @function iro-ease-in-circ($x) { | ||
460 | @return iro-cubic-bezier(0.6, 0.04, 0.98, 0.335, $x); | ||
461 | } | ||
462 | |||
463 | /// | ||
464 | /// Circular easing function (out direction). | ||
465 | /// | ||
466 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
467 | /// | ||
468 | /// @return {number} | ||
469 | /// | ||
470 | @function iro-ease-out-circ($x) { | ||
471 | @return iro-cubic-bezier(0.075, 0.82, 0.165, 1, $x); | ||
472 | } | ||
473 | |||
474 | /// | ||
475 | /// Circular easing function (in-out direction). | ||
476 | /// | ||
477 | /// @param {number} $x - Progress between 0 and 1 inclusive | ||
478 | /// | ||
479 | /// @return {number} | ||
480 | /// | ||
481 | @function iro-ease-in-out-circ($x) { | ||
482 | @return iro-cubic-bezier(0.785, 0.135, 0.15, 0.86, $x); | ||
483 | } | ||