diff options
author | Otavio Pontes <otavio@profusion.mobi> | 2013-12-02 14:59:43 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2013-12-02 15:02:40 +0900 |
commit | afd8a238d199a90e95a826c31a091e9adb11cc1e (patch) | |
tree | 5a91790c9133be4139f31d57515b3a8f4a806828 /src/lib/ecore | |
parent | 0b605c5daad9dd4934f9f0a4ae3ce2c00aadf63c (diff) |
Adding the cubic-bezier curve to edje transitions
Summary: Adding an option to use a cubic-bezier curve in edje transitions.
Reviewers: Sachiel, cedric, raster
Reviewed By: raster
CC: raster
Differential Revision: https://phab.enlightenment.org/D319
Diffstat (limited to 'src/lib/ecore')
-rw-r--r-- | src/lib/ecore/Ecore_Common.h | 68 | ||||
-rw-r--r-- | src/lib/ecore/ecore_anim.c | 120 |
2 files changed, 176 insertions, 12 deletions
diff --git a/src/lib/ecore/Ecore_Common.h b/src/lib/ecore/Ecore_Common.h index bf6d1de8ed..39feead947 100644 --- a/src/lib/ecore/Ecore_Common.h +++ b/src/lib/ecore/Ecore_Common.h | |||
@@ -1899,7 +1899,8 @@ enum _Ecore_Pos_Map /* Position mappings */ | |||
1899 | ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */ | 1899 | ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */ |
1900 | ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ | 1900 | ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ |
1901 | ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */ | 1901 | ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */ |
1902 | ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */ | 1902 | ECORE_POS_MAP_SPRING, /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */ |
1903 | ECORE_POS_MAP_CUBIC_BEZIER /**< Follow the cubic-bezier curve calculated with the points (x1, y1), (x2, y2) */ | ||
1903 | }; | 1904 | }; |
1904 | typedef enum _Ecore_Pos_Map Ecore_Pos_Map; | 1905 | typedef enum _Ecore_Pos_Map Ecore_Pos_Map; |
1905 | 1906 | ||
@@ -2010,6 +2011,71 @@ EAPI double ecore_animator_frametime_get(void); | |||
2010 | * @since 1.1.0 | 2011 | * @since 1.1.0 |
2011 | */ | 2012 | */ |
2012 | EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); | 2013 | EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); |
2014 | |||
2015 | /** | ||
2016 | * @brief Maps an input position from 0.0 to 1.0 along a timeline to a | ||
2017 | * position in a different curve. | ||
2018 | * | ||
2019 | * @param pos The input position to map | ||
2020 | * @param map The mapping to use | ||
2021 | * @param v_size The size of the v array. | ||
2022 | * @param v An array with the double parameters to be used by the mapping. | ||
2023 | * NULL if not used. | ||
2024 | * @return The mapped value | ||
2025 | * | ||
2026 | * Takes an input position (0.0 to 1.0) and maps to a new position (normally | ||
2027 | * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it | ||
2028 | * has "overshot" the mark) using some interpolation (mapping) algorithm. | ||
2029 | * | ||
2030 | * This function useful to create non-linear animations. It offers a variety | ||
2031 | * of possible animation curves to be used: | ||
2032 | * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos | ||
2033 | * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up | ||
2034 | * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down | ||
2035 | * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end | ||
2036 | * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v[0] being a | ||
2037 | * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0 | ||
2038 | * being much more pronounced accelerate (squared), 3.0 being cubed, etc. | ||
2039 | * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v[0] being a | ||
2040 | * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0 | ||
2041 | * being much more pronounced decelerate (squared), 3.0 being cubed, etc. | ||
2042 | * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down | ||
2043 | * at end, v[0] being a power factor, 0.0 being linear, 1.0 being | ||
2044 | * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal | ||
2045 | * (squared), 3.0 being cubed, etc. | ||
2046 | * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v[0], interpolated via | ||
2047 | * power of v2 curve | ||
2048 | * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to | ||
2049 | * the ground at 1.0, and bounce v2 times, with decay factor of v[0] | ||
2050 | * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest | ||
2051 | * position 1.0, and wobble v2 times, with decay factor of v[0] | ||
2052 | * @li ECORE_POS_MAP_CUBIC_BEZIER - Use an interpolated cubic-bezier curve | ||
2053 | * ajusted with parameters from v[0] to v[3]. | ||
2054 | * @note When not listed v has no effect. | ||
2055 | * | ||
2056 | * @image html ecore-pos-map.png | ||
2057 | * @image latex ecore-pos-map.eps width=\textwidth | ||
2058 | * | ||
2059 | * One way to use this would be: | ||
2060 | * @code | ||
2061 | * double pos; // input position in a timeline from 0.0 to 1.0 | ||
2062 | * double out; // output position after mapping | ||
2063 | * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position | ||
2064 | * int x, y; // x & y are the calculated position | ||
2065 | * double v[2] = {1.8, 7}; | ||
2066 | * | ||
2067 | * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 2, v); | ||
2068 | * x = (x1 * out) + (x2 * (1.0 - out)); | ||
2069 | * y = (y1 * out) + (y2 * (1.0 - out)); | ||
2070 | * move_my_object_to(myobject, x, y); | ||
2071 | * @endcode | ||
2072 | * This will make an animation that bounces 7 each times diminishing by a | ||
2073 | * factor of 1.8. | ||
2074 | * | ||
2075 | * @see _Ecore_Pos_Map | ||
2076 | */ | ||
2077 | EAPI double ecore_animator_pos_map_n(double pos, Ecore_Pos_Map map, int v_size, double v[]); | ||
2078 | |||
2013 | /** | 2079 | /** |
2014 | * @brief Set the source of animator ticks for the mainloop | 2080 | * @brief Set the source of animator ticks for the mainloop |
2015 | * | 2081 | * |
diff --git a/src/lib/ecore/ecore_anim.c b/src/lib/ecore/ecore_anim.c index 7b33f71385..dd76dafcbf 100644 --- a/src/lib/ecore/ecore_anim.c +++ b/src/lib/ecore/ecore_anim.c | |||
@@ -313,6 +313,72 @@ _pos_map_spring(double pos, | |||
313 | return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay; | 313 | return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay; |
314 | } | 314 | } |
315 | 315 | ||
316 | static double | ||
317 | _cubic_bezier_a (double a1, double a2) | ||
318 | { | ||
319 | return 1.0 - 3.0 * a2 + 3.0 * a1; | ||
320 | } | ||
321 | |||
322 | static double | ||
323 | _cubic_bezier_b (double a1, double a2) | ||
324 | { | ||
325 | return 3.0 * a2 - 6.0 * a1; | ||
326 | } | ||
327 | |||
328 | static double | ||
329 | _cubic_bezier_c(double a1) | ||
330 | { | ||
331 | return 3.0 * a1; | ||
332 | } | ||
333 | |||
334 | static double | ||
335 | _cubic_bezier_calc(double t, | ||
336 | double a1, | ||
337 | double a2) | ||
338 | { | ||
339 | return ((_cubic_bezier_a(a1, a2) * t + | ||
340 | _cubic_bezier_b(a1, a2)) * t + | ||
341 | _cubic_bezier_c(a1)) * t; | ||
342 | } | ||
343 | |||
344 | static double | ||
345 | _cubic_bezier_slope_get(double t, | ||
346 | double a1, | ||
347 | double a2) | ||
348 | { | ||
349 | return 3.0 * _cubic_bezier_a(a1, a2) * t * t + | ||
350 | 2.0 * _cubic_bezier_b(a1, a2) * t + | ||
351 | _cubic_bezier_c(a1); | ||
352 | } | ||
353 | |||
354 | static double | ||
355 | _cubic_bezier_t_get(double a, | ||
356 | double x1, | ||
357 | double x2) | ||
358 | { | ||
359 | double guess_t = a; | ||
360 | for (int i = 0; i < 4; ++i) | ||
361 | { | ||
362 | double current_slope = _cubic_bezier_slope_get(a, x1, x2); | ||
363 | if (current_slope == 0.0) | ||
364 | return guess_t; | ||
365 | double current_x = _cubic_bezier_calc(guess_t, x1, x2) - a; | ||
366 | guess_t -= current_x / current_slope; | ||
367 | } | ||
368 | return guess_t; | ||
369 | } | ||
370 | |||
371 | static double | ||
372 | _pos_map_cubic_bezier(double pos, | ||
373 | double x1, | ||
374 | double y1, | ||
375 | double x2, | ||
376 | double y2) | ||
377 | { | ||
378 | if (x1 == y1 && x2 == y2) return pos; | ||
379 | return _cubic_bezier_calc(_cubic_bezier_t_get(pos, x1, x2), y1, y2); | ||
380 | } | ||
381 | |||
316 | #define DBL_TO(Fp) eina_f32p32_double_to(Fp) | 382 | #define DBL_TO(Fp) eina_f32p32_double_to(Fp) |
317 | #define DBL_FROM(D) eina_f32p32_double_from(D) | 383 | #define DBL_FROM(D) eina_f32p32_double_from(D) |
318 | #define INT_FROM(I) eina_f32p32_int_from(I) | 384 | #define INT_FROM(I) eina_f32p32_int_from(I) |
@@ -323,11 +389,13 @@ _pos_map_spring(double pos, | |||
323 | #define MUL(A, B) eina_f32p32_mul(A, B) | 389 | #define MUL(A, B) eina_f32p32_mul(A, B) |
324 | 390 | ||
325 | EAPI double | 391 | EAPI double |
326 | ecore_animator_pos_map(double pos, | 392 | ecore_animator_pos_map_n(double pos, |
327 | Ecore_Pos_Map map, | 393 | Ecore_Pos_Map map, |
328 | double v1, | 394 | int v_size, |
329 | double v2) | 395 | double v[]) |
330 | { | 396 | { |
397 | double v0 = 0, v1 = 0, v2 = 0, v3 = 0; | ||
398 | |||
331 | /* purely functional - locking not required */ | 399 | /* purely functional - locking not required */ |
332 | if (pos >= 1.0) return 1.0; | 400 | if (pos >= 1.0) return 1.0; |
333 | else if (pos <= 0.0) | 401 | else if (pos <= 0.0) |
@@ -353,30 +421,47 @@ ecore_animator_pos_map(double pos, | |||
353 | return pos; | 421 | return pos; |
354 | 422 | ||
355 | case ECORE_POS_MAP_ACCELERATE_FACTOR: | 423 | case ECORE_POS_MAP_ACCELERATE_FACTOR: |
356 | pos = _pos_map_accel_factor(pos, v1); | 424 | if (v_size > 0) v0 = v[0]; |
425 | pos = _pos_map_accel_factor(pos, v0); | ||
357 | return pos; | 426 | return pos; |
358 | 427 | ||
359 | case ECORE_POS_MAP_DECELERATE_FACTOR: | 428 | case ECORE_POS_MAP_DECELERATE_FACTOR: |
360 | pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1); | 429 | if (v_size > 0) v0 = v[0]; |
430 | pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v0); | ||
361 | return pos; | 431 | return pos; |
362 | 432 | ||
363 | case ECORE_POS_MAP_SINUSOIDAL_FACTOR: | 433 | case ECORE_POS_MAP_SINUSOIDAL_FACTOR: |
364 | if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0; | 434 | if (v_size > 0) v0 = v[0]; |
365 | else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0); | 435 | if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v0) / 2.0; |
436 | else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v0) / 2.0); | ||
366 | return pos; | 437 | return pos; |
367 | 438 | ||
368 | case ECORE_POS_MAP_DIVISOR_INTERP: | 439 | case ECORE_POS_MAP_DIVISOR_INTERP: |
369 | pos = _pos_map_pow(pos, v1, (int)v2); | 440 | if (v_size > 0) v0 = v[0]; |
441 | if (v_size > 1) v1 = v[1]; | ||
442 | pos = _pos_map_pow(pos, v0, (int)v1); | ||
370 | return pos; | 443 | return pos; |
371 | 444 | ||
372 | case ECORE_POS_MAP_BOUNCE: | 445 | case ECORE_POS_MAP_BOUNCE: |
373 | pos = _pos_map_spring(pos, (int)v2, v1); | 446 | if (v_size > 0) v0 = v[0]; |
447 | if (v_size > 1) v1 = v[1]; | ||
448 | pos = _pos_map_spring(pos, (int)v1, v0); | ||
374 | if (pos < 0.0) pos = -pos; | 449 | if (pos < 0.0) pos = -pos; |
375 | pos = 1.0 - pos; | 450 | pos = 1.0 - pos; |
376 | return pos; | 451 | return pos; |
377 | 452 | ||
378 | case ECORE_POS_MAP_SPRING: | 453 | case ECORE_POS_MAP_SPRING: |
379 | pos = 1.0 - _pos_map_spring(pos, (int)v2, v1); | 454 | if (v_size > 0) v0 = v[0]; |
455 | if (v_size > 1) v1 = v[1]; | ||
456 | pos = 1.0 - _pos_map_spring(pos, (int)v1, v0); | ||
457 | return pos; | ||
458 | |||
459 | case ECORE_POS_MAP_CUBIC_BEZIER: | ||
460 | if (v_size > 0) v0 = v[0]; | ||
461 | if (v_size > 1) v1 = v[1]; | ||
462 | if (v_size > 2) v2 = v[2]; | ||
463 | if (v_size > 3) v3 = v[3]; | ||
464 | pos = _pos_map_cubic_bezier(pos, v0, v1, v2, v3); | ||
380 | return pos; | 465 | return pos; |
381 | 466 | ||
382 | default: | 467 | default: |
@@ -386,6 +471,19 @@ ecore_animator_pos_map(double pos, | |||
386 | return pos; | 471 | return pos; |
387 | } | 472 | } |
388 | 473 | ||
474 | EAPI double | ||
475 | ecore_animator_pos_map(double pos, | ||
476 | Ecore_Pos_Map map, | ||
477 | double v1, | ||
478 | double v2) | ||
479 | { | ||
480 | double v[2]; | ||
481 | |||
482 | v[0] = v1; | ||
483 | v[1] = v2; | ||
484 | return ecore_animator_pos_map_n(pos, map, 2, v); | ||
485 | } | ||
486 | |||
389 | EAPI void * | 487 | EAPI void * |
390 | ecore_animator_del(Ecore_Animator *obj) | 488 | ecore_animator_del(Ecore_Animator *obj) |
391 | { | 489 | { |