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