OLD | NEW |
1 // | 1 // |
2 // Copyright 2014 Google Inc. All rights reserved. | 2 // Copyright 2014 Google Inc. All rights reserved. |
3 // | 3 // |
4 // Use of this source code is governed by a BSD-style | 4 // Use of this source code is governed by a BSD-style |
5 // license that can be found in the LICENSE file or at | 5 // license that can be found in the LICENSE file or at |
6 // https://developers.google.com/open-source/licenses/bsd | 6 // https://developers.google.com/open-source/licenses/bsd |
7 // | 7 // |
8 | 8 |
9 part of charted.core.interpolators; | 9 part of charted.core.interpolators; |
10 | 10 |
11 const String EASE_TYPE_LINEAR = 'linear'; | 11 const String EASE_TYPE_LINEAR = 'linear'; |
12 const String EASE_TYPE_POLY = 'poly'; | 12 const String EASE_TYPE_POLY = 'poly'; |
13 const String EASE_TYPE_QUAD = 'quad'; | 13 const String EASE_TYPE_QUAD = 'quad'; |
14 const String EASE_TYPE_CUBIC = 'cubic'; | 14 const String EASE_TYPE_CUBIC = 'cubic'; |
15 const String EASE_TYPE_SIN = 'sin'; | 15 const String EASE_TYPE_SIN = 'sin'; |
16 const String EASE_TYPE_EXP = 'exp'; | 16 const String EASE_TYPE_EXP = 'exp'; |
17 const String EASE_TYPE_CIRCLE = 'circle'; | 17 const String EASE_TYPE_CIRCLE = 'circle'; |
18 const String EASE_TYPE_ELASTIC = 'elastic'; | 18 const String EASE_TYPE_ELASTIC = 'elastic'; |
19 const String EASE_TYPE_BACK = 'back'; | 19 const String EASE_TYPE_BACK = 'back'; |
20 const String EASE_TYPE_BOUNCE = 'bounce'; | 20 const String EASE_TYPE_BOUNCE = 'bounce'; |
21 | 21 |
22 const String EASE_MODE_IN = 'in'; | 22 const String EASE_MODE_IN = 'in'; |
23 const String EASE_MODE_OUT = 'out'; | 23 const String EASE_MODE_OUT = 'out'; |
24 const String EASE_MODE_IN_OUT = 'in-out'; | 24 const String EASE_MODE_IN_OUT = 'in-out'; |
25 const String EASE_MODE_OUT_IN = 'out-in'; | 25 const String EASE_MODE_OUT_IN = 'out-in'; |
26 | 26 |
27 /// [EasingFunction] manipulates progression of an animation. The returned | 27 /// [EasingFunction] manipulates progression of an animation. The returned |
28 /// value is passed to an [Interpolator] to generate intermediate state. | 28 /// value is passed to an [Interpolator] to generate intermediate state. |
29 typedef num EasingFunction(num t); | 29 typedef num EasingFunction(num t); |
30 | 30 |
31 /// Alters behavior of the [EasingFunction]. Takes [fn] and returns an | 31 /// Alters behavior of the [EasingFunction]. Takes [fn] and returns an |
32 /// altered [EasingFunction]. | 32 /// altered [EasingFunction]. |
33 typedef EasingFunction EasingModeFunction(EasingFunction fn); | 33 typedef EasingFunction EasingModeFunction(EasingFunction fn); |
34 | 34 |
35 /// Creates an easing function based on type and mode. | 35 /// Creates an easing function based on type and mode. |
36 EasingFunction easingFunctionByName( | 36 EasingFunction easingFunctionByName(String type, |
37 String type, [String mode = EASE_MODE_IN, List params]) { | 37 [String mode = EASE_MODE_IN, List params]) { |
38 const Map easingTypes = const { | 38 const Map easingTypes = const { |
39 EASE_TYPE_LINEAR: identityFunction, | 39 EASE_TYPE_LINEAR: identityFunction, |
40 EASE_TYPE_POLY: easePoly, | 40 EASE_TYPE_POLY: easePoly, |
41 EASE_TYPE_QUAD: easeQuad, | 41 EASE_TYPE_QUAD: easeQuad, |
42 EASE_TYPE_CUBIC: easeCubic, | 42 EASE_TYPE_CUBIC: easeCubic, |
43 EASE_TYPE_SIN: easeSin, | 43 EASE_TYPE_SIN: easeSin, |
44 EASE_TYPE_EXP: easeExp, | 44 EASE_TYPE_EXP: easeExp, |
45 EASE_TYPE_CIRCLE: easeCircle, | 45 EASE_TYPE_CIRCLE: easeCircle, |
46 EASE_TYPE_ELASTIC: easeElastic, | 46 EASE_TYPE_ELASTIC: easeElastic, |
47 EASE_TYPE_BACK: easeBack, | 47 EASE_TYPE_BACK: easeBack, |
48 EASE_TYPE_BOUNCE: easeBounce | 48 EASE_TYPE_BOUNCE: easeBounce |
49 }; | 49 }; |
50 | 50 |
51 const Map easingModes = const { | 51 const Map easingModes = const { |
52 EASE_MODE_IN: identityFunction, | 52 EASE_MODE_IN: identityFunction, |
53 EASE_MODE_OUT: reverseEasingFn, | 53 EASE_MODE_OUT: reverseEasingFn, |
54 EASE_MODE_IN_OUT: reflectEasingFn, | 54 EASE_MODE_IN_OUT: reflectEasingFn, |
55 EASE_MODE_OUT_IN: reflectReverseEasingFn | 55 EASE_MODE_OUT_IN: reflectReverseEasingFn |
56 }; | 56 }; |
57 | 57 |
58 const Map customEasingFunctions = const { | 58 const Map customEasingFunctions = const { |
59 '$EASE_TYPE_CUBIC-$EASE_MODE_IN_OUT': easeCubicInOut | 59 '$EASE_TYPE_CUBIC-$EASE_MODE_IN_OUT': easeCubicInOut |
60 }; | 60 }; |
61 | 61 |
62 assert(easingTypes.containsKey(type)); | 62 assert(easingTypes.containsKey(type)); |
63 assert(easingModes.containsKey(mode)); | 63 assert(easingModes.containsKey(mode)); |
64 | 64 |
65 EasingFunction fn; | 65 EasingFunction fn; |
66 if (customEasingFunctions.containsKey('$type-$mode')) { | 66 if (customEasingFunctions.containsKey('$type-$mode')) { |
67 fn = Function.apply(customEasingFunctions['$type-$mode'], params); | 67 fn = Function.apply(customEasingFunctions['$type-$mode'], params); |
68 } else { | 68 } else { |
69 fn = Function.apply(easingTypes[type], params); | 69 fn = Function.apply(easingTypes[type], params); |
70 fn = easingModes[mode](fn); | 70 fn = easingModes[mode](fn); |
71 } | 71 } |
72 return clampEasingFn(fn); | 72 return clampEasingFn(fn); |
73 } | 73 } |
74 | 74 |
75 | |
76 /// Clamps transition progress to stay between 0.0 and 1.0 | 75 /// Clamps transition progress to stay between 0.0 and 1.0 |
77 EasingFunction clampEasingFn(EasingFunction f) => | 76 EasingFunction clampEasingFn(EasingFunction f) => |
78 (t) => t <= 0 ? 0 : t >= 1 ? 1 : f(t); | 77 (t) => t <= 0 ? 0 : t >= 1 ? 1 : f(t); |
79 | 78 |
80 | |
81 // | 79 // |
82 // Implementation of easing modes. | 80 // Implementation of easing modes. |
83 // | 81 // |
84 | 82 |
85 EasingFunction reverseEasingFn(EasingFunction f) => | 83 EasingFunction reverseEasingFn(EasingFunction f) => (t) => 1 - f(1 - t); |
86 (t) => 1 - f(1 - t); | |
87 | 84 |
88 EasingFunction reflectEasingFn(EasingFunction f) => | 85 EasingFunction reflectEasingFn(EasingFunction f) => |
89 (t) => .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t))); | 86 (t) => .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t))); |
90 | 87 |
91 EasingFunction reflectReverseEasingFn(EasingFunction f) => | 88 EasingFunction reflectReverseEasingFn(EasingFunction f) => |
92 reflectEasingFn(reverseEasingFn(f)); | 89 reflectEasingFn(reverseEasingFn(f)); |
93 | 90 |
94 | |
95 // | 91 // |
96 // Implementation of easing function generators. | 92 // Implementation of easing function generators. |
97 // | 93 // |
98 | 94 |
99 EasingFunction easePoly([e = 1]) => (t) => math.pow(t, e); | 95 EasingFunction easePoly([e = 1]) => (t) => math.pow(t, e); |
100 | 96 |
101 EasingFunction easeElastic([a = 1, p = 0.45]) { | 97 EasingFunction easeElastic([a = 1, p = 0.45]) { |
102 var s = p / 2 * math.PI * math.asin(1 / a); | 98 var s = p / 2 * math.PI * math.asin(1 / a); |
103 return (t) => 1 + a * math.pow(2, -10 * t) * | 99 return (t) => |
104 math.sin((t - s) * 2 * math.PI / p); | 100 1 + a * math.pow(2, -10 * t) * math.sin((t - s) * 2 * math.PI / p); |
105 } | 101 } |
106 | 102 |
107 EasingFunction easeBack([s = 1.70158]) => | 103 EasingFunction easeBack([s = 1.70158]) => (num t) => t * t * ((s + 1) * t - s); |
108 (num t) => t * t * ((s + 1) * t - s); | |
109 | 104 |
110 EasingFunction easeQuad() => (num t) => t * t; | 105 EasingFunction easeQuad() => (num t) => t * t; |
111 | 106 |
112 EasingFunction easeCubic() => (num t) => t * t * t; | 107 EasingFunction easeCubic() => (num t) => t * t * t; |
113 | 108 |
114 EasingFunction easeCubicInOut() => | 109 EasingFunction easeCubicInOut() => (num t) { |
115 (num t) { | |
116 if (t <= 0) return 0; | 110 if (t <= 0) return 0; |
117 if (t >= 1) return 1; | 111 if (t >= 1) return 1; |
118 var t2 = t * t, | 112 var t2 = t * t, t3 = t2 * t; |
119 t3 = t2 * t; | |
120 return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); | 113 return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); |
121 }; | 114 }; |
122 | 115 |
123 EasingFunction easeSin() => | 116 EasingFunction easeSin() => (num t) => 1 - math.cos(t * math.PI / 2); |
124 (num t) => 1 - math.cos(t * math.PI / 2); | |
125 | 117 |
126 EasingFunction easeExp() => | 118 EasingFunction easeExp() => (num t) => math.pow(2, 10 * (t - 1)); |
127 (num t) => math.pow(2, 10 * (t - 1)); | |
128 | 119 |
129 EasingFunction easeCircle() => | 120 EasingFunction easeCircle() => (num t) => 1 - math.sqrt(1 - t * t); |
130 (num t) => 1 - math.sqrt(1 - t * t); | |
131 | 121 |
132 EasingFunction easeBounce() => | 122 EasingFunction easeBounce() => (num t) => t < 1 / 2.75 |
133 (num t) => t < 1 / 2.75 ? | 123 ? 7.5625 * t * t |
134 7.5625 * t * t : t < 2 / 2.75 ? | 124 : t < 2 / 2.75 |
135 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? | 125 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 |
136 7.5625 * (t -= 2.25 / 2.75) * t + .9375 | 126 : t < 2.5 / 2.75 |
137 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; | 127 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 |
| 128 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; |
OLD | NEW |