Release Clutter 1.11.4 (snapshot)
[profile/ivi/clutter.git] / clutter / clutter-easing.c
1 #include "config.h"
2
3 #include "clutter-easing.h"
4
5 #include <math.h>
6
7 double
8 clutter_linear (double t,
9                 double d)
10 {
11   return t / d;
12 }
13
14 double
15 clutter_ease_in_quad (double t,
16                       double d)
17 {
18   double p = t / d;
19
20   return p * p;
21 }
22
23 double
24 clutter_ease_out_quad (double t,
25                        double d)
26 {
27   double p = t / d;
28
29   return -1.0 * p * (p - 2);
30 }
31
32 double
33 clutter_ease_in_out_quad (double t,
34                           double d)
35 {
36   double p = t / (d / 2);
37
38   if (p < 1)
39     return 0.5 * p * p;
40
41   p -= 1;
42
43   return -0.5 * (p * (p - 2) - 1);
44 }
45
46 double
47 clutter_ease_in_cubic (double t,
48                        double d)
49 {
50   double p = t / d;
51
52   return p * p * p;
53 }
54
55 double
56 clutter_ease_out_cubic (double t,
57                         double d)
58 {
59   double p = t / d - 1;
60
61   return p * p * p + 1;
62 }
63
64 double
65 clutter_ease_in_out_cubic (double t,
66                            double d)
67 {
68   double p = t / (d / 2);
69
70   if (p < 1)
71     return 0.5 * p * p * p;
72
73   p -= 2;
74
75   return 0.5 * (p * p * p + 2);
76 }
77
78 double
79 clutter_ease_in_quart (double t,
80                        double d)
81 {
82   double p = t / d;
83
84   return p * p * p * p;
85 }
86
87 double
88 clutter_ease_out_quart (double t,
89                         double d)
90 {
91   double p = t / d - 1;
92
93   return -1.0 * (p * p * p * p - 1);
94 }
95
96 double
97 clutter_ease_in_out_quart (double t,
98                            double d)
99 {
100   double p = t / (d / 2);
101
102   if (p < 1)
103     return 0.5 * p * p * p * p;
104
105   p -= 2;
106
107   return -0.5 * (p * p * p * p - 2);
108 }
109
110 double
111 clutter_ease_in_quint (double t,
112                        double d)
113  {
114   double p = t / d;
115
116   return p * p * p * p * p;
117 }
118
119 double
120 clutter_ease_out_quint (double t,
121                         double d)
122 {
123   double p = t / d - 1;
124
125   return p * p * p * p * p + 1;
126 }
127
128 double
129 clutter_ease_in_out_quint (double t,
130                            double d)
131 {
132   double p = t / (d / 2);
133
134   if (p < 1)
135     return 0.5 * p * p * p * p * p;
136
137   p -= 2;
138
139   return 0.5 * (p * p * p * p * p + 2);
140 }
141
142 double
143 clutter_ease_in_sine (double t,
144                       double d)
145 {
146   return -1.0 * cos (t / d * G_PI_2) + 1.0;
147 }
148
149 double
150 clutter_ease_out_sine (double t,
151                        double d)
152 {
153   return sin (t / d * G_PI_2);
154 }
155
156 double
157 clutter_ease_in_out_sine (double t,
158                           double d)
159 {
160   return -0.5 * (cos (G_PI * t / d) - 1);
161 }
162
163 double
164 clutter_ease_in_expo (double t,
165                       double d)
166 {
167   return (t == 0) ? 0.0 : pow (2, 10 * (t / d - 1));
168 }
169
170 double
171 clutter_ease_out_expo (double t,
172                        double d)
173 {
174   return (t == d) ? 1.0 : -pow (2, -10 * t / d) + 1;
175 }
176
177 double
178 clutter_ease_in_out_expo (double t,
179                           double d)
180 {
181   double p;
182
183   if (t == 0)
184     return 0.0;
185
186   if (t == d)
187     return 1.0;
188
189   p = t / (d / 2);
190
191   if (p < 1)
192     return 0.5 * pow (2, 10 * (p - 1));
193
194   p -= 1;
195
196   return 0.5 * (-pow (2, -10 * p) + 2);
197 }
198
199 double
200 clutter_ease_in_circ (double t,
201                       double d)
202 {
203   double p = t / d;
204
205   return -1.0 * (sqrt (1 - p * p) - 1);
206 }
207
208 double
209 clutter_ease_out_circ (double t,
210                        double d)
211 {
212   double p = t / d - 1;
213
214   return sqrt (1 - p * p);
215 }
216
217 double
218 clutter_ease_in_out_circ (double t,
219                           double d)
220 {
221   double p = t / (d / 2);
222
223   if (p < 1)
224     return -0.5 * (sqrt (1 - p * p) - 1);
225
226   p -= 2;
227
228   return 0.5 * (sqrt (1 - p * p) + 1);
229 }
230
231 double
232 clutter_ease_in_elastic (double t,
233                          double d)
234 {
235   double p = d * .3;
236   double s = p / 4;
237   double q = t / d;
238
239   if (q == 1)
240     return 1.0;
241
242   q -= 1;
243
244   return -(pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p));
245 }
246
247 double
248 clutter_ease_out_elastic (double t,
249                           double d)
250 {
251   double p = d * .3;
252   double s = p / 4;
253   double q = t / d;
254
255   if (q == 1)
256     return 1.0;
257
258   return pow (2, -10 * q) * sin ((q * d - s) * (2 * G_PI) / p) + 1.0;
259 }
260
261 double
262 clutter_ease_in_out_elastic (double t,
263                              double d)
264 {
265   double p = d * (.3 * 1.5);
266   double s = p / 4;
267   double q = t / (d / 2);
268
269   if (q == 2)
270     return 1.0;
271
272   if (q < 1)
273     {
274       q -= 1;
275
276       return -.5 * (pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p));
277     }
278   else
279     {
280       q -= 1;
281
282       return pow (2, -10 * q)
283            * sin ((q * d - s) * (2 * G_PI) / p)
284            * .5 + 1.0;
285     }
286 }
287
288 double
289 clutter_ease_in_back (double t,
290                       double d)
291 {
292   double p = t / d;
293
294   return p * p * ((1.70158 + 1) * p - 1.70158);
295 }
296
297 double
298 clutter_ease_out_back (double t,
299                        double d)
300 {
301   double p = t / d - 1;
302
303   return p * p * ((1.70158 + 1) * p + 1.70158) + 1;
304 }
305
306 double
307 clutter_ease_in_out_back (double t,
308                           double d)
309 {
310   double p = t / (d / 2);
311   double s = 1.70158 * 1.525;
312
313   if (p < 1)
314     return 0.5 * (p * p * ((s + 1) * p - s));
315
316   p -= 2;
317
318   return 0.5 * (p * p * ((s + 1) * p + s) + 2);
319 }
320
321 static inline double
322 ease_out_bounce_internal (double t,
323                           double d)
324 {
325   double p = t / d;
326
327   if (p < (1 / 2.75))
328     {
329       return 7.5625 * p * p;
330     }
331   else if (p < (2 / 2.75))
332     {
333       p -= (1.5 / 2.75);
334
335       return 7.5625 * p * p + .75;
336     }
337   else if (p < (2.5 / 2.75))
338     {
339       p -= (2.25 / 2.75);
340
341       return 7.5625 * p * p + .9375;
342     }
343   else
344     {
345       p -= (2.625 / 2.75);
346
347       return 7.5625 * p * p + .984375;
348     }
349 }
350
351 static inline double
352 ease_in_bounce_internal (double t,
353                          double d)
354 {
355   return 1.0 - ease_out_bounce_internal (d - t, d);
356 }
357
358 double
359 clutter_ease_in_bounce (double t,
360                         double d)
361 {
362   return ease_in_bounce_internal (t, d);
363 }
364
365 double
366 clutter_ease_out_bounce (double t,
367                          double d)
368 {
369   return ease_out_bounce_internal (t, d);
370 }
371
372 double
373 clutter_ease_in_out_bounce (double t,
374                             double d)
375 {
376   if (t < d / 2)
377     return ease_in_bounce_internal (t * 2, d) * 0.5;
378   else
379     return ease_out_bounce_internal (t * 2 - d, d) * 0.5 + 1.0 * 0.5;
380 }
381
382 /*< private >
383  * _clutter_animation_modes:
384  *
385  * A mapping of animation modes and easing functions.
386  */
387 static const struct {
388   ClutterAnimationMode mode;
389   ClutterEasingFunc func;
390   const char *name;
391 } _clutter_animation_modes[] = {
392   { CLUTTER_CUSTOM_MODE,         NULL, "custom" },
393
394   { CLUTTER_LINEAR,              clutter_linear, "linear" },
395   { CLUTTER_EASE_IN_QUAD,        clutter_ease_in_quad, "easeInQuad" },
396   { CLUTTER_EASE_OUT_QUAD,       clutter_ease_out_quad, "easeOutQuad" },
397   { CLUTTER_EASE_IN_OUT_QUAD,    clutter_ease_in_out_quad, "easeInOutQuad" },
398   { CLUTTER_EASE_IN_CUBIC,       clutter_ease_in_cubic, "easeInCubic" },
399   { CLUTTER_EASE_OUT_CUBIC,      clutter_ease_out_cubic, "easeOutCubic" },
400   { CLUTTER_EASE_IN_OUT_CUBIC,   clutter_ease_in_out_cubic, "easeInOutCubic" },
401   { CLUTTER_EASE_IN_QUART,       clutter_ease_in_quart, "easeInQuart" },
402   { CLUTTER_EASE_OUT_QUART,      clutter_ease_out_quart, "easeOutQuart" },
403   { CLUTTER_EASE_IN_OUT_QUART,   clutter_ease_in_out_quart, "easeInOutQuart" },
404   { CLUTTER_EASE_IN_QUINT,       clutter_ease_in_quint, "easeInQuint" },
405   { CLUTTER_EASE_OUT_QUINT,      clutter_ease_out_quint, "easeOutQuint" },
406   { CLUTTER_EASE_IN_OUT_QUINT,   clutter_ease_in_out_quint, "easeInOutQuint" },
407   { CLUTTER_EASE_IN_SINE,        clutter_ease_in_sine, "easeInSine" },
408   { CLUTTER_EASE_OUT_SINE,       clutter_ease_out_sine, "easeOutSine" },
409   { CLUTTER_EASE_IN_OUT_SINE,    clutter_ease_in_out_sine, "easeInOutSine" },
410   { CLUTTER_EASE_IN_EXPO,        clutter_ease_in_expo, "easeInExpo" },
411   { CLUTTER_EASE_OUT_EXPO,       clutter_ease_out_expo, "easeOutExpo" },
412   { CLUTTER_EASE_IN_OUT_EXPO,    clutter_ease_in_out_expo, "easeInOutExpo" },
413   { CLUTTER_EASE_IN_CIRC,        clutter_ease_in_circ, "easeInCirc" },
414   { CLUTTER_EASE_OUT_CIRC,       clutter_ease_out_circ, "easeOutCirc" },
415   { CLUTTER_EASE_IN_OUT_CIRC,    clutter_ease_in_out_circ, "easeInOutCirc" },
416   { CLUTTER_EASE_IN_ELASTIC,     clutter_ease_in_elastic, "easeInElastic" },
417   { CLUTTER_EASE_OUT_ELASTIC,    clutter_ease_out_elastic, "easeOutElastic" },
418   { CLUTTER_EASE_IN_OUT_ELASTIC, clutter_ease_in_out_elastic, "easeInOutElastic" },
419   { CLUTTER_EASE_IN_BACK,        clutter_ease_in_back, "easeInBack" },
420   { CLUTTER_EASE_OUT_BACK,       clutter_ease_out_back, "easeOutBack" },
421   { CLUTTER_EASE_IN_OUT_BACK,    clutter_ease_in_out_back, "easeInOutBack" },
422   { CLUTTER_EASE_IN_BOUNCE,      clutter_ease_in_bounce, "easeInBounce" },
423   { CLUTTER_EASE_OUT_BOUNCE,     clutter_ease_out_bounce, "easeOutBounce" },
424   { CLUTTER_EASE_IN_OUT_BOUNCE,  clutter_ease_in_out_bounce, "easeInOutBounce" },
425
426   { CLUTTER_ANIMATION_LAST,      NULL, "sentinel" },
427 };
428
429 ClutterEasingFunc
430 clutter_get_easing_func_for_mode (ClutterAnimationMode mode)
431 {
432   g_assert (_clutter_animation_modes[mode].mode == mode);
433   g_assert (_clutter_animation_modes[mode].func != NULL);
434
435   return _clutter_animation_modes[mode].func;
436 }
437
438 const char *
439 clutter_get_easing_name_for_mode (ClutterAnimationMode mode)
440 {
441   g_assert (_clutter_animation_modes[mode].mode == mode);
442   g_assert (_clutter_animation_modes[mode].func != NULL);
443
444   return _clutter_animation_modes[mode].name;
445 }
446
447 double
448 clutter_easing_for_mode (ClutterAnimationMode mode,
449                          double               t,
450                          double               d)
451 {
452   g_assert (_clutter_animation_modes[mode].mode == mode);
453   g_assert (_clutter_animation_modes[mode].func != NULL);
454
455   return _clutter_animation_modes[mode].func (t, d);
456 }