motion 10.4.0 → 10.5.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +0 -19
  2. package/dist/main.cjs.js +11 -13
  3. package/dist/main.es.js +7 -6
  4. package/dist/motion.min.js +1 -1
  5. package/dist/motion.umd.js +8 -1292
  6. package/dist/size-index.js +1 -0
  7. package/lib/index.js +5 -0
  8. package/lib/index.js.map +1 -0
  9. package/package.json +5 -138
  10. package/types/index.d.ts +3 -7
  11. package/types/index.d.ts.map +1 -0
  12. package/CHANGELOG.md +0 -103
  13. package/LICENSE +0 -21
  14. package/dist/react.cjs.js +0 -9
  15. package/dist/react.es.js +0 -1
  16. package/dist/size-animate-dom.js +0 -1
  17. package/dist/size-animate-style.js +0 -1
  18. package/dist/size-react.js +0 -1
  19. package/dist/size-spring.js +0 -1
  20. package/dist/size-timeline-dom.js +0 -1
  21. package/dist/size-webpack-animate.js +0 -1
  22. package/dist/targets/dom/animate-style.cjs.js +0 -182
  23. package/dist/targets/dom/animate-style.es.js +0 -178
  24. package/dist/targets/dom/animate.cjs.js +0 -42
  25. package/dist/targets/dom/animate.es.js +0 -38
  26. package/dist/targets/dom/data.cjs.js +0 -18
  27. package/dist/targets/dom/data.es.js +0 -14
  28. package/dist/targets/dom/style.cjs.js +0 -22
  29. package/dist/targets/dom/style.es.js +0 -18
  30. package/dist/targets/dom/timeline/index.cjs.js +0 -190
  31. package/dist/targets/dom/timeline/index.es.js +0 -185
  32. package/dist/targets/dom/timeline/utils/calc-time.cjs.js +0 -23
  33. package/dist/targets/dom/timeline/utils/calc-time.es.js +0 -19
  34. package/dist/targets/dom/timeline/utils/edit.cjs.js +0 -36
  35. package/dist/targets/dom/timeline/utils/edit.es.js +0 -31
  36. package/dist/targets/dom/timeline/utils/sort.cjs.js +0 -14
  37. package/dist/targets/dom/timeline/utils/sort.es.js +0 -10
  38. package/dist/targets/dom/utils/apply.cjs.js +0 -9
  39. package/dist/targets/dom/utils/apply.es.js +0 -4
  40. package/dist/targets/dom/utils/controls.cjs.js +0 -59
  41. package/dist/targets/dom/utils/controls.es.js +0 -54
  42. package/dist/targets/dom/utils/css-var.cjs.js +0 -29
  43. package/dist/targets/dom/utils/css-var.es.js +0 -23
  44. package/dist/targets/dom/utils/defaults.cjs.js +0 -13
  45. package/dist/targets/dom/utils/defaults.es.js +0 -9
  46. package/dist/targets/dom/utils/easing.cjs.js +0 -18
  47. package/dist/targets/dom/utils/easing.es.js +0 -10
  48. package/dist/targets/dom/utils/feature-detection.cjs.js +0 -31
  49. package/dist/targets/dom/utils/feature-detection.es.js +0 -27
  50. package/dist/targets/dom/utils/get-style-name.cjs.js +0 -13
  51. package/dist/targets/dom/utils/get-style-name.es.js +0 -9
  52. package/dist/targets/dom/utils/keyframes.cjs.js +0 -16
  53. package/dist/targets/dom/utils/keyframes.es.js +0 -11
  54. package/dist/targets/dom/utils/options.cjs.js +0 -13
  55. package/dist/targets/dom/utils/options.es.js +0 -9
  56. package/dist/targets/dom/utils/resolve-elements.cjs.js +0 -22
  57. package/dist/targets/dom/utils/resolve-elements.es.js +0 -18
  58. package/dist/targets/dom/utils/stop-animation.cjs.js +0 -19
  59. package/dist/targets/dom/utils/stop-animation.es.js +0 -15
  60. package/dist/targets/dom/utils/time.cjs.js +0 -7
  61. package/dist/targets/dom/utils/time.es.js +0 -3
  62. package/dist/targets/dom/utils/transforms.cjs.js +0 -85
  63. package/dist/targets/dom/utils/transforms.es.js +0 -74
  64. package/dist/targets/js/NumberAnimation.cjs.js +0 -144
  65. package/dist/targets/js/NumberAnimation.es.js +0 -140
  66. package/dist/targets/js/easing/cubic-bezier.cjs.js +0 -57
  67. package/dist/targets/js/easing/cubic-bezier.es.js +0 -53
  68. package/dist/targets/js/easing/glide/generator.cjs.js +0 -99
  69. package/dist/targets/js/easing/glide/generator.es.js +0 -95
  70. package/dist/targets/js/easing/glide/index.cjs.js +0 -10
  71. package/dist/targets/js/easing/glide/index.es.js +0 -6
  72. package/dist/targets/js/easing/spring/generator.cjs.js +0 -64
  73. package/dist/targets/js/easing/spring/generator.es.js +0 -57
  74. package/dist/targets/js/easing/spring/index.cjs.js +0 -10
  75. package/dist/targets/js/easing/spring/index.es.js +0 -6
  76. package/dist/targets/js/easing/steps.cjs.js +0 -15
  77. package/dist/targets/js/easing/steps.es.js +0 -11
  78. package/dist/targets/js/easing/utils/create-generator-easing.cjs.js +0 -71
  79. package/dist/targets/js/easing/utils/create-generator-easing.es.js +0 -67
  80. package/dist/targets/js/easing/utils/get-function.cjs.js +0 -37
  81. package/dist/targets/js/easing/utils/get-function.es.js +0 -33
  82. package/dist/targets/js/easing/utils/has-reached-target.cjs.js +0 -10
  83. package/dist/targets/js/easing/utils/has-reached-target.es.js +0 -6
  84. package/dist/targets/js/easing/utils/pregenerate-keyframes.cjs.js +0 -34
  85. package/dist/targets/js/easing/utils/pregenerate-keyframes.es.js +0 -30
  86. package/dist/targets/js/utils/get-easing.cjs.js +0 -14
  87. package/dist/targets/js/utils/get-easing.es.js +0 -10
  88. package/dist/targets/js/utils/interpolate.cjs.js +0 -35
  89. package/dist/targets/js/utils/interpolate.es.js +0 -31
  90. package/dist/targets/js/utils/offset.cjs.js +0 -22
  91. package/dist/targets/js/utils/offset.es.js +0 -17
  92. package/dist/targets/react/animated.cjs.js +0 -126
  93. package/dist/targets/react/animated.es.js +0 -101
  94. package/dist/targets/react/context.cjs.js +0 -9
  95. package/dist/targets/react/context.es.js +0 -5
  96. package/dist/targets/react/hooks/use-animation.cjs.js +0 -47
  97. package/dist/targets/react/hooks/use-animation.es.js +0 -43
  98. package/dist/targets/react/hooks/use-exit.cjs.js +0 -27
  99. package/dist/targets/react/hooks/use-exit.es.js +0 -23
  100. package/dist/targets/react/hooks/use-gesture-state.cjs.js +0 -17
  101. package/dist/targets/react/hooks/use-gesture-state.es.js +0 -13
  102. package/dist/targets/react/hooks/use-hover.cjs.js +0 -24
  103. package/dist/targets/react/hooks/use-hover.es.js +0 -20
  104. package/dist/targets/react/hooks/use-press.cjs.js +0 -25
  105. package/dist/targets/react/hooks/use-press.es.js +0 -21
  106. package/dist/targets/react/hooks/use-viewport.cjs.js +0 -37
  107. package/dist/targets/react/hooks/use-viewport.es.js +0 -33
  108. package/dist/targets/react/index.cjs.js +0 -17
  109. package/dist/targets/react/index.es.js +0 -13
  110. package/dist/targets/react/utils/has-changed.cjs.js +0 -24
  111. package/dist/targets/react/utils/has-changed.es.js +0 -19
  112. package/dist/targets/react/utils/keyframes.cjs.js +0 -38
  113. package/dist/targets/react/utils/keyframes.es.js +0 -34
  114. package/dist/targets/react/utils/poses.cjs.js +0 -14
  115. package/dist/targets/react/utils/poses.es.js +0 -10
  116. package/dist/targets/react/utils/update-target.cjs.js +0 -20
  117. package/dist/targets/react/utils/update-target.es.js +0 -16
  118. package/dist/utils/array.cjs.js +0 -14
  119. package/dist/utils/array.es.js +0 -9
  120. package/dist/utils/clamp.cjs.js +0 -7
  121. package/dist/utils/clamp.es.js +0 -3
  122. package/dist/utils/is-number.cjs.js +0 -7
  123. package/dist/utils/is-number.es.js +0 -3
  124. package/dist/utils/mix.cjs.js +0 -28
  125. package/dist/utils/mix.es.js +0 -24
  126. package/dist/utils/noop.cjs.js +0 -9
  127. package/dist/utils/noop.es.js +0 -4
  128. package/dist/utils/progress.cjs.js +0 -20
  129. package/dist/utils/progress.es.js +0 -16
  130. package/dist/utils/stagger.cjs.js +0 -38
  131. package/dist/utils/stagger.es.js +0 -32
  132. package/dist/utils/velocity-per-second.cjs.js +0 -15
  133. package/dist/utils/velocity-per-second.es.js +0 -11
  134. package/dist/utils/wrap.cjs.js +0 -10
  135. package/dist/utils/wrap.es.js +0 -6
  136. package/react/package.json +0 -6
  137. package/types/react-entry.d.ts +0 -2
  138. package/types/targets/dom/animate-style.d.ts +0 -2
  139. package/types/targets/dom/animate.d.ts +0 -2
  140. package/types/targets/dom/data.d.ts +0 -2
  141. package/types/targets/dom/style.d.ts +0 -3
  142. package/types/targets/dom/timeline/index.d.ts +0 -15
  143. package/types/targets/dom/timeline/types.d.ts +0 -13
  144. package/types/targets/dom/timeline/utils/calc-time.d.ts +0 -2
  145. package/types/targets/dom/timeline/utils/edit.d.ts +0 -4
  146. package/types/targets/dom/timeline/utils/sort.d.ts +0 -2
  147. package/types/targets/dom/types.d.ts +0 -114
  148. package/types/targets/dom/utils/apply.d.ts +0 -3
  149. package/types/targets/dom/utils/controls.d.ts +0 -12
  150. package/types/targets/dom/utils/css-var.d.ts +0 -3
  151. package/types/targets/dom/utils/defaults.d.ts +0 -8
  152. package/types/targets/dom/utils/easing.d.ts +0 -6
  153. package/types/targets/dom/utils/feature-detection.d.ts +0 -8
  154. package/types/targets/dom/utils/get-style-name.d.ts +0 -1
  155. package/types/targets/dom/utils/keyframes.d.ts +0 -3
  156. package/types/targets/dom/utils/options.d.ts +0 -2
  157. package/types/targets/dom/utils/resolve-elements.d.ts +0 -4
  158. package/types/targets/dom/utils/stop-animation.d.ts +0 -6
  159. package/types/targets/dom/utils/time.d.ts +0 -1
  160. package/types/targets/dom/utils/transforms.d.ts +0 -20
  161. package/types/targets/js/NumberAnimation.d.ts +0 -24
  162. package/types/targets/js/easing/cubic-bezier.d.ts +0 -1
  163. package/types/targets/js/easing/glide/generator.d.ts +0 -5
  164. package/types/targets/js/easing/glide/index.d.ts +0 -2
  165. package/types/targets/js/easing/glide/types.d.ts +0 -14
  166. package/types/targets/js/easing/spring/generator.d.ts +0 -6
  167. package/types/targets/js/easing/spring/index.d.ts +0 -2
  168. package/types/targets/js/easing/spring/types.d.ts +0 -10
  169. package/types/targets/js/easing/steps.d.ts +0 -3
  170. package/types/targets/js/easing/utils/create-generator-easing.d.ts +0 -3
  171. package/types/targets/js/easing/utils/get-function.d.ts +0 -3
  172. package/types/targets/js/easing/utils/has-reached-target.d.ts +0 -1
  173. package/types/targets/js/easing/utils/pregenerate-keyframes.d.ts +0 -7
  174. package/types/targets/js/types.d.ts +0 -12
  175. package/types/targets/js/utils/get-easing.d.ts +0 -1
  176. package/types/targets/js/utils/interpolate.d.ts +0 -2
  177. package/types/targets/js/utils/offset.d.ts +0 -2
  178. package/types/targets/react/animated.d.ts +0 -3
  179. package/types/targets/react/context.d.ts +0 -3
  180. package/types/targets/react/hooks/use-animation.d.ts +0 -4
  181. package/types/targets/react/hooks/use-exit.d.ts +0 -3
  182. package/types/targets/react/hooks/use-gesture-state.d.ts +0 -4
  183. package/types/targets/react/hooks/use-hover.d.ts +0 -4
  184. package/types/targets/react/hooks/use-press.d.ts +0 -4
  185. package/types/targets/react/hooks/use-viewport.d.ts +0 -4
  186. package/types/targets/react/index.d.ts +0 -2
  187. package/types/targets/react/types.d.ts +0 -108
  188. package/types/targets/react/utils/has-changed.d.ts +0 -2
  189. package/types/targets/react/utils/keyframes.d.ts +0 -3
  190. package/types/targets/react/utils/poses.d.ts +0 -2
  191. package/types/targets/react/utils/supported-elements.d.ts +0 -8
  192. package/types/targets/react/utils/update-target.d.ts +0 -3
  193. package/types/utils/array.d.ts +0 -2
  194. package/types/utils/clamp.d.ts +0 -1
  195. package/types/utils/interpolate.d.ts +0 -0
  196. package/types/utils/is-number.d.ts +0 -1
  197. package/types/utils/mix.d.ts +0 -1
  198. package/types/utils/noop.d.ts +0 -2
  199. package/types/utils/progress.d.ts +0 -1
  200. package/types/utils/stagger.d.ts +0 -12
  201. package/types/utils/value-types.d.ts +0 -0
  202. package/types/utils/velocity-per-second.d.ts +0 -1
  203. package/types/utils/wrap.d.ts +0 -1
@@ -2,813 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
3
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Motion = {}));
5
- }(this, (function (exports) { 'use strict';
6
-
7
- const data = new WeakMap();
8
- function getAnimationData(element) {
9
- if (!data.has(element)) {
10
- data.set(element, {
11
- transforms: [],
12
- animations: {},
13
- generators: {},
14
- prevGeneratorState: {},
15
- });
16
- }
17
- return data.get(element);
18
- }
19
-
20
- function addUniqueItem(array, item) {
21
- array.indexOf(item) === -1 && array.push(item);
22
- }
23
- function removeItem(arr, item) {
24
- const index = arr.indexOf(item);
25
- index > -1 && arr.splice(index, 1);
26
- }
27
-
28
- const noop = () => { };
29
- const noopReturn = (v) => v;
30
-
31
- /**
32
- * A list of all transformable axes. We'll use this list to generated a version
33
- * of each axes for each transform.
34
- */
35
- const axes = ["", "X", "Y", "Z"];
36
- /**
37
- * An ordered array of each transformable value. By default, transform values
38
- * will be sorted to this order.
39
- */
40
- const order = ["translate", "scale", "rotate", "skew"];
41
- const transformAlias = {
42
- x: "translateX",
43
- y: "translateY",
44
- z: "translateZ",
45
- };
46
- const rotation = {
47
- syntax: "<angle>",
48
- initialValue: "0deg",
49
- toDefaultUnit: (v) => v + "deg",
50
- };
51
- const baseTransformProperties = {
52
- translate: {
53
- syntax: "<length-percentage>",
54
- initialValue: "0px",
55
- toDefaultUnit: (v) => v + "px",
56
- },
57
- rotate: rotation,
58
- scale: {
59
- syntax: "<number>",
60
- initialValue: 1,
61
- toDefaultUnit: noopReturn,
62
- },
63
- skew: rotation,
64
- };
65
- const transformDefinitions = new Map();
66
- const asTransformCssVar = (name) => `--motion-${name}`;
67
- /**
68
- * Generate a list of every possible transform key
69
- */
70
- const transforms = ["x", "y", "z"];
71
- order.forEach((name) => {
72
- axes.forEach((axis) => {
73
- transforms.push(name + axis);
74
- transformDefinitions.set(asTransformCssVar(name + axis), baseTransformProperties[name]);
75
- });
76
- });
77
- /**
78
- * A function to use with Array.sort to sort transform keys by their default order.
79
- */
80
- const compareTransformOrder = (a, b) => transforms.indexOf(a) - transforms.indexOf(b);
81
- /**
82
- * Provide a quick way to check if a string is the name of a transform
83
- */
84
- const transformLookup = new Set(transforms);
85
- const isTransform = (name) => transformLookup.has(name);
86
- const addTransformToElement = (element, name) => {
87
- // Map x to translateX etc
88
- if (transformAlias[name])
89
- name = transformAlias[name];
90
- const { transforms } = getAnimationData(element);
91
- addUniqueItem(transforms, name);
92
- element.style.transform = buildTransformTemplate(transforms);
93
- };
94
- const buildTransformTemplate = (transforms) => transforms
95
- .sort(compareTransformOrder)
96
- .reduce(transformListToString, "")
97
- .trim();
98
- const transformListToString = (template, name) => `${template} ${name}(var(${asTransformCssVar(name)}))`;
99
-
100
- const isCssVar = (name) => name.startsWith("--");
101
- const registeredProperties = new Set();
102
- function registerCssVariable(name) {
103
- if (registeredProperties.has(name))
104
- return;
105
- registeredProperties.add(name);
106
- try {
107
- const { syntax, initialValue } = transformDefinitions.has(name)
108
- ? transformDefinitions.get(name)
109
- : {};
110
- CSS.registerProperty({
111
- name,
112
- inherits: false,
113
- syntax,
114
- initialValue,
115
- });
116
- }
117
- catch (e) { }
118
- }
119
-
120
- const ms = (seconds) => seconds * 1000;
121
-
122
- const isNumber = (value) => typeof value === "number";
123
-
124
- const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
125
- const isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
126
- const isCustomEasing = (easing) => typeof easing === "object" &&
127
- Boolean(easing.createAnimation);
128
- const convertEasing = (easing) => isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
129
- const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
130
-
131
- const testAnimation = (keyframes) => document.createElement("div").animate(keyframes, { duration: 0.001 });
132
- const featureTests = {
133
- cssRegisterProperty: () => typeof CSS !== "undefined" &&
134
- Object.hasOwnProperty.call(CSS, "registerProperty"),
135
- waapi: () => Object.hasOwnProperty.call(Element.prototype, "animate"),
136
- partialKeyframes: () => {
137
- try {
138
- testAnimation({ opacity: [1] });
139
- }
140
- catch (e) {
141
- return false;
142
- }
143
- return true;
144
- },
145
- finished: () => Boolean(testAnimation({ opacity: [0, 1] }).finished),
146
- };
147
- const results = {};
148
- const supports = {};
149
- for (const key in featureTests) {
150
- supports[key] = () => {
151
- if (results[key] === undefined)
152
- results[key] = featureTests[key]();
153
- return results[key];
154
- };
155
- }
156
-
157
- const cssVariableRenderer = (element, name) => (latest) => element.style.setProperty(name, latest);
158
- const styleRenderer = (element, name) => (latest) => (element.style[name] = latest);
159
-
160
- const defaults = {
161
- duration: 0.3,
162
- delay: 0,
163
- endDelay: 0,
164
- repeat: 0,
165
- easing: "ease",
166
- };
167
-
168
- /*
169
- Bezier function generator
170
-
171
- This has been modified from Gaëtan Renaudeau's BezierEasing
172
- https://github.com/gre/bezier-easing/blob/master/src/index.js
173
- https://github.com/gre/bezier-easing/blob/master/LICENSE
174
-
175
- I've removed the newtonRaphsonIterate algo because in benchmarking it
176
- wasn't noticiably faster than binarySubdivision, indeed removing it
177
- usually improved times, depending on the curve.
178
-
179
- I also removed the lookup table, as for the added bundle size and loop we're
180
- only cutting ~4 or so subdivision iterations. I bumped the max iterations up
181
- to 12 to compensate and this still tended to be faster for no perceivable
182
- loss in accuracy.
183
-
184
- Usage
185
- const easeOut = cubicBezier(.17,.67,.83,.67);
186
- const x = easeOut(0.5); // returns 0.627...
187
- */
188
- // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
189
- const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) * t;
190
- const subdivisionPrecision = 0.0000001;
191
- const subdivisionMaxIterations = 12;
192
- function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
193
- let currentX;
194
- let currentT;
195
- let i = 0;
196
- do {
197
- currentT = lowerBound + (upperBound - lowerBound) / 2.0;
198
- currentX = calcBezier(currentT, mX1, mX2) - x;
199
- if (currentX > 0.0) {
200
- upperBound = currentT;
201
- }
202
- else {
203
- lowerBound = currentT;
204
- }
205
- } while (Math.abs(currentX) > subdivisionPrecision &&
206
- ++i < subdivisionMaxIterations);
207
- return currentT;
208
- }
209
- function cubicBezier(mX1, mY1, mX2, mY2) {
210
- // If this is a linear gradient, return linear easing
211
- if (mX1 === mY1 && mX2 === mY2)
212
- return noopReturn;
213
- const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
214
- // If animation is at start/end, return t without easing
215
- return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
216
- }
217
-
218
- const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
219
-
220
- const steps = (steps, direction = "end") => (progress) => {
221
- progress =
222
- direction === "end" ? Math.min(progress, 0.999) : Math.max(progress, 0.001);
223
- const expanded = progress * steps;
224
- const rounded = direction === "end" ? Math.floor(expanded) : Math.ceil(expanded);
225
- return clamp(0, 1, rounded / steps);
226
- };
227
-
228
- const namedEasings = {
229
- ease: cubicBezier(0.25, 0.1, 0.25, 1.0),
230
- "ease-in": cubicBezier(0.42, 0.0, 1.0, 1.0),
231
- "ease-in-out": cubicBezier(0.42, 0.0, 0.58, 1.0),
232
- "ease-out": cubicBezier(0.0, 0.0, 0.58, 1.0),
233
- };
234
- const functionArgsRegex = /\((.*?)\)/;
235
- function getEasingFunction(definition) {
236
- // If already an easing function, return
237
- if (typeof definition === "function")
238
- return definition;
239
- // If an easing curve definition, return bezier function
240
- if (Array.isArray(definition))
241
- return cubicBezier(...definition);
242
- // If we have a predefined easing function, return
243
- if (namedEasings[definition])
244
- return namedEasings[definition];
245
- // If this is a steps function, attempt to create easing curve
246
- if (definition.startsWith("steps")) {
247
- const args = functionArgsRegex.exec(definition);
248
- if (args) {
249
- const argsArray = args[1].split(",");
250
- return steps(parseFloat(argsArray[0]), argsArray[1].trim());
251
- }
252
- }
253
- return noopReturn;
254
- }
255
-
256
- /*
257
- Value in range from progress
258
-
259
- Given a lower limit and an upper limit, we return the value within
260
- that range as expressed by progress (usually a number from 0 to 1)
261
-
262
- So progress = 0.5 would change
263
-
264
- from -------- to
265
-
266
- to
267
-
268
- from ---- to
269
-
270
- E.g. from = 10, to = 20, progress = 0.5 => 15
271
-
272
- @param [number]: Lower limit of range
273
- @param [number]: Upper limit of range
274
- @param [number]: The progress between lower and upper limits expressed 0-1
275
- @return [number]: Value as calculated from progress within range (not limited within range)
276
- */
277
- const mix = (from, to, progress) => -progress * from + progress * to + from;
278
-
279
- /*
280
- Progress within given range
281
-
282
- Given a lower limit and an upper limit, we return the progress
283
- (expressed as a number 0-1) represented by the given value.
284
-
285
- @param [number]: Lower limit
286
- @param [number]: Upper limit
287
- @param [number]: Value to find progress within given range
288
- @return [number]: Progress of value within range as expressed 0-1
289
- */
290
- const progress = (from, to, value) => {
291
- return to - from === 0 ? 1 : (value - from) / (to - from);
292
- };
293
-
294
- const wrap = (min, max, v) => {
295
- const rangeSize = max - min;
296
- return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
297
- };
298
-
299
- function getEasingForSegment(easing, i) {
300
- return isEasingList(easing)
301
- ? easing[wrap(0, easing.length, i)]
302
- : easing;
303
- }
304
-
305
- function fillOffset(offset, remaining) {
306
- const min = offset[offset.length - 1];
307
- for (let i = 1; i <= remaining; i++) {
308
- const offsetProgress = progress(0, remaining, i);
309
- offset.push(mix(min, 1, offsetProgress));
310
- }
311
- }
312
- function defaultOffset(length) {
313
- const offset = [0];
314
- fillOffset(offset, length - 1);
315
- return offset;
316
- }
317
-
318
- const clampProgress = (p) => Math.min(1, Math.max(p, 0));
319
- function slowInterpolateNumbers(output, input = defaultOffset(output.length), easing = noopReturn) {
320
- const length = output.length;
321
- /**
322
- * If the input length is lower than the output we
323
- * fill the input to match. This currently assumes the input
324
- * is an animation progress value so is a good candidate for
325
- * moving outside the function.
326
- */
327
- const remainder = length - input.length;
328
- remainder > 0 && fillOffset(input, remainder);
329
- return (t) => {
330
- let i = 0;
331
- for (; i < length - 2; i++) {
332
- if (t < input[i + 1])
333
- break;
334
- }
335
- let progressInRange = clampProgress(progress(input[i], input[i + 1], t));
336
- const segmentEasing = getEasingForSegment(easing, i);
337
- progressInRange = segmentEasing(progressInRange);
338
- return mix(output[i], output[i + 1], progressInRange);
339
- };
340
- }
341
-
342
- class NumberAnimation {
343
- constructor(output, keyframes = [0, 1], { easing = defaults.easing, duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, offset, direction = "normal", } = {}) {
344
- this.startTime = 0;
345
- this.rate = 1;
346
- this.t = 0;
347
- this.cancelTimestamp = 0;
348
- this.playState = "idle";
349
- this.finished = new Promise((resolve, reject) => {
350
- this.resolve = resolve;
351
- this.reject = reject;
352
- });
353
- const totalDuration = duration * (repeat + 1);
354
- /**
355
- * We don't currently support custom easing (spring, glide etc) in NumberAnimation
356
- * (although this is completely possible), so this will have been hydrated by
357
- * animateStyle.
358
- */
359
- if (isCustomEasing(easing))
360
- easing = "ease";
361
- const interpolate = slowInterpolateNumbers(keyframes, offset, isEasingList(easing)
362
- ? easing.map(getEasingFunction)
363
- : getEasingFunction(easing));
364
- this.tick = (timestamp) => {
365
- if (this.pauseTime)
366
- timestamp = this.pauseTime;
367
- let t = (timestamp - this.startTime) * this.rate;
368
- this.t = t;
369
- // Convert to seconds
370
- t /= 1000;
371
- // Rebase on delay
372
- t = Math.max(t - delay, 0);
373
- /**
374
- * If this animation has finished, set the current time
375
- * to the total duration.
376
- */
377
- if (this.playState === "finished")
378
- t = totalDuration;
379
- /**
380
- * Get the current progress (0-1) of the animation. If t is >
381
- * than duration we'll get values like 2.5 (midway through the
382
- * third iteration)
383
- */
384
- const progress = t / duration;
385
- // TODO progress += iterationStart
386
- /**
387
- * Get the current iteration (0 indexed). For instance the floor of
388
- * 2.5 is 2.
389
- */
390
- let currentIteration = Math.floor(progress);
391
- /**
392
- * Get the current progress of the iteration by taking the remainder
393
- * so 2.5 is 0.5 through iteration 2
394
- */
395
- let iterationProgress = progress % 1.0;
396
- if (!iterationProgress && progress >= 1) {
397
- iterationProgress = 1;
398
- }
399
- /**
400
- * If iteration progress is 1 we count that as the end
401
- * of the previous iteration.
402
- */
403
- iterationProgress === 1 && currentIteration--;
404
- /**
405
- * Reverse progress if we're not running in "normal" direction
406
- */
407
- const iterationIsOdd = currentIteration % 2;
408
- if (direction === "reverse" ||
409
- (direction === "alternate" && iterationIsOdd) ||
410
- (direction === "alternate-reverse" && !iterationIsOdd)) {
411
- iterationProgress = 1 - iterationProgress;
412
- }
413
- const latest = interpolate(t >= totalDuration ? 1 : Math.min(iterationProgress, 1));
414
- output(latest);
415
- const isAnimationFinished = this.playState === "finished" || t >= totalDuration + endDelay;
416
- if (isAnimationFinished) {
417
- this.playState = "finished";
418
- this.resolve(latest);
419
- }
420
- else if (this.playState !== "idle") {
421
- requestAnimationFrame(this.tick);
422
- }
423
- };
424
- this.play();
425
- }
426
- play() {
427
- const now = performance.now();
428
- this.playState = "running";
429
- if (this.pauseTime) {
430
- this.startTime = now - (this.pauseTime - this.startTime);
431
- }
432
- else if (!this.startTime) {
433
- this.startTime = now;
434
- }
435
- this.pauseTime = undefined;
436
- requestAnimationFrame(this.tick);
437
- }
438
- pause() {
439
- this.playState = "paused";
440
- this.pauseTime = performance.now();
441
- }
442
- finish() {
443
- this.playState = "finished";
444
- this.tick(0);
445
- }
446
- cancel() {
447
- this.playState = "idle";
448
- this.tick(this.cancelTimestamp);
449
- this.reject(false);
450
- }
451
- reverse() {
452
- this.rate *= -1;
453
- }
454
- commitStyles() {
455
- this.cancelTimestamp = performance.now();
456
- }
457
- get currentTime() {
458
- return this.t;
459
- }
460
- set currentTime(t) {
461
- if (this.pauseTime || this.rate === 0) {
462
- this.pauseTime = t;
463
- }
464
- else {
465
- this.startTime = performance.now() - t / this.rate;
466
- }
467
- }
468
- get playbackRate() {
469
- return this.rate;
470
- }
471
- set playbackRate(rate) {
472
- this.rate = rate;
473
- }
474
- }
475
-
476
- function hydrateKeyframes(keyframes, readInitialValue) {
477
- for (let i = 0; i < keyframes.length; i++) {
478
- if (keyframes[i] === null) {
479
- keyframes[i] = i ? keyframes[i - 1] : readInitialValue();
480
- }
481
- }
482
- return keyframes;
483
- }
484
- const keyframesList = (keyframes) => Array.isArray(keyframes) ? keyframes : [keyframes];
485
-
486
- const style = {
487
- get: (element, name) => {
488
- let value = isCssVar(name)
489
- ? element.style.getPropertyValue(name)
490
- : getComputedStyle(element)[name];
491
- if (!value && value !== 0) {
492
- const definition = transformDefinitions.get(name);
493
- if (definition)
494
- value = definition.initialValue;
495
- }
496
- return value;
497
- },
498
- };
499
-
500
- function getStyleName(key) {
501
- if (transformAlias[key])
502
- key = transformAlias[key];
503
- return isTransform(key) ? asTransformCssVar(key) : key;
504
- }
505
-
506
- function stopAnimation(animation) {
507
- if (!animation)
508
- return;
509
- // Suppress error thrown by WAAPI
510
- try {
511
- /**
512
- * commitStyles has overhead so we only want to commit and cancel
513
- */
514
- animation.playState !== "finished" && animation.commitStyles();
515
- animation.cancel();
516
- }
517
- catch (e) { }
518
- }
519
-
520
- function animateStyle(element, key, keyframesDefinition, options = {}) {
521
- let animation;
522
- let { duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, easing = defaults.easing, direction, offset, allowWebkitAcceleration = false, } = options;
523
- const data = getAnimationData(element);
524
- let canAnimateNatively = supports.waapi();
525
- let render = noop;
526
- const valueIsTransform = isTransform(key);
527
- /**
528
- * If this is an individual transform, we need to map its
529
- * key to a CSS variable and update the element's transform style
530
- */
531
- valueIsTransform && addTransformToElement(element, key);
532
- const name = getStyleName(key);
533
- /**
534
- * Get definition of value, this will be used to convert numerical
535
- * keyframes into the default value type.
536
- */
537
- const definition = transformDefinitions.get(name);
538
- /**
539
- * Stop the current animation, if any. Because this will trigger
540
- * commitStyles (DOM writes) and we might later trigger DOM reads,
541
- * this is fired now and we return a factory function to create
542
- * the actual animation that can get called in batch,
543
- */
544
- stopAnimation(data.animations[name]);
545
- /**
546
- * Batchable factory function containing all DOM reads.
547
- */
548
- return () => {
549
- const readInitialValue = () => { var _a, _b; return (_b = (_a = style.get(element, name)) !== null && _a !== void 0 ? _a : definition === null || definition === void 0 ? void 0 : definition.initialValue) !== null && _b !== void 0 ? _b : 0; };
550
- /**
551
- * Replace null values with the previous keyframe value, or read
552
- * it from the DOM if it's the first keyframe.
553
- */
554
- let keyframes = hydrateKeyframes(keyframesList(keyframesDefinition), readInitialValue);
555
- if (isCustomEasing(easing)) {
556
- const custom = easing.createAnimation(keyframes, readInitialValue, valueIsTransform, name, data);
557
- easing = custom.easing;
558
- if (custom.keyframes !== undefined)
559
- keyframes = custom.keyframes;
560
- if (custom.duration !== undefined)
561
- duration = custom.duration;
562
- }
563
- /**
564
- * If this is a CSS variable we need to register it with the browser
565
- * before it can be animated natively. We also set it with setProperty
566
- * rather than directly onto the element.style object.
567
- */
568
- if (isCssVar(name)) {
569
- render = cssVariableRenderer(element, name);
570
- if (supports.cssRegisterProperty()) {
571
- registerCssVariable(name);
572
- }
573
- else {
574
- canAnimateNatively = false;
575
- }
576
- }
577
- else {
578
- render = styleRenderer(element, name);
579
- }
580
- /**
581
- * If we can animate this value with WAAPI, do so. Currently this only
582
- * feature detects CSS.registerProperty but could check WAAPI too.
583
- */
584
- if (canAnimateNatively) {
585
- /**
586
- * Convert numbers to default value types. Currently this only supports
587
- * transforms but it could also support other value types.
588
- */
589
- if (definition) {
590
- keyframes = keyframes.map((value) => isNumber(value) ? definition.toDefaultUnit(value) : value);
591
- }
592
- /**
593
- * If this browser doesn't support partial/implicit keyframes we need to
594
- * explicitly provide one.
595
- */
596
- if (!supports.partialKeyframes() && keyframes.length === 1) {
597
- keyframes.unshift(readInitialValue());
598
- }
599
- const animationOptions = {
600
- delay: ms(delay),
601
- duration: ms(duration),
602
- endDelay: ms(endDelay),
603
- easing: !isEasingList(easing) ? convertEasing(easing) : undefined,
604
- direction,
605
- iterations: repeat + 1,
606
- fill: "both",
607
- };
608
- animation = element.animate({
609
- [name]: keyframes,
610
- offset,
611
- easing: isEasingList(easing) ? easing.map(convertEasing) : undefined,
612
- }, animationOptions);
613
- /**
614
- * Polyfill finished Promise in browsers that don't support it
615
- */
616
- if (!animation.finished) {
617
- animation.finished = new Promise((resolve, reject) => {
618
- animation.onfinish = resolve;
619
- animation.oncancel = reject;
620
- });
621
- }
622
- const target = keyframes[keyframes.length - 1];
623
- animation.finished
624
- .then(() => {
625
- // Apply styles to target
626
- render(target);
627
- // Ensure fill modes don't persist
628
- animation.cancel();
629
- })
630
- .catch(noop);
631
- /**
632
- * This forces Webkit to run animations on the main thread by exploiting
633
- * this condition:
634
- * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp?rev=281238#L1099
635
- *
636
- * This fixes Webkit's timing bugs, like accelerated animations falling
637
- * out of sync with main thread animations and massive delays in starting
638
- * accelerated animations in WKWebView.
639
- */
640
- if (!allowWebkitAcceleration)
641
- animation.playbackRate = 1.000001;
642
- /**
643
- * If we can't animate the value natively then we can fallback to the numbers-only
644
- * polyfill for transforms. All keyframes must be numerical.
645
- */
646
- }
647
- else if (valueIsTransform && keyframes.every(isNumber)) {
648
- /**
649
- * If we only have a single keyframe, we need to create an initial keyframe by reading
650
- * the current value from the DOM.
651
- */
652
- if (keyframes.length === 1) {
653
- keyframes.unshift(parseFloat(readInitialValue()));
654
- }
655
- if (definition) {
656
- const applyStyle = render;
657
- render = (v) => applyStyle(definition.toDefaultUnit(v));
658
- }
659
- animation = new NumberAnimation(render, keyframes, Object.assign(Object.assign({}, options), { duration,
660
- easing }));
661
- }
662
- else {
663
- const target = keyframes[keyframes.length - 1];
664
- render(definition && isNumber(target)
665
- ? definition.toDefaultUnit(target)
666
- : target);
667
- }
668
- data.animations[name] = animation;
669
- /**
670
- * When an animation finishes, delete the reference to the previous animation.
671
- */
672
- animation === null || animation === void 0 ? void 0 : animation.finished.then(() => {
673
- data.animations[name] = undefined;
674
- data.generators[name] = undefined;
675
- data.prevGeneratorState[name] = undefined;
676
- }).catch(noop);
677
- return animation;
678
- };
679
- }
680
-
681
- const getOptions = (options, key) =>
682
- /**
683
- * TODO: Make test for this
684
- * Always return a new object otherwise delay is overwritten by results of stagger
685
- * and this results in no stagger
686
- */
687
- options[key] ? Object.assign(Object.assign({}, options), options[key]) : Object.assign({}, options);
688
-
689
- function resolveElements(elements, selectorCache) {
690
- var _a;
691
- if (typeof elements === "string") {
692
- if (selectorCache) {
693
- (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = document.querySelectorAll(elements));
694
- elements = selectorCache[elements];
695
- }
696
- else {
697
- elements = document.querySelectorAll(elements);
698
- }
699
- }
700
- else if (elements instanceof Element) {
701
- elements = [elements];
702
- }
703
- return Array.from(elements);
704
- }
705
-
706
- const createAnimation = (factory) => factory();
707
- const createAnimations = (animationFactory, duration) => new Proxy({
708
- animations: animationFactory.map(createAnimation).filter(Boolean),
709
- duration,
710
- }, controls);
711
- /**
712
- * TODO:
713
- * Currently this returns the first animation, ideally it would return
714
- * the first active animation.
715
- */
716
- const getActiveAnimation = (state) => state.animations[0];
717
- const controls = {
718
- get: (target, key) => {
719
- var _a, _b;
720
- switch (key) {
721
- case "duration":
722
- return target.duration;
723
- case "currentTime":
724
- let time = ((_a = getActiveAnimation(target)) === null || _a === void 0 ? void 0 : _a[key]) || 0;
725
- return time ? time / 1000 : 0;
726
- case "playbackRate":
727
- return (_b = getActiveAnimation(target)) === null || _b === void 0 ? void 0 : _b[key];
728
- case "finished":
729
- if (!target.finished) {
730
- target.finished = Promise.all(target.animations.map(selectFinished)).catch(noop);
731
- }
732
- return target.finished;
733
- case "stop":
734
- return () => target.animations.forEach(stopAnimation);
735
- default:
736
- return () => target.animations.forEach((animation) => animation[key]());
737
- }
738
- },
739
- set: (target, key, value) => {
740
- switch (key) {
741
- case "currentTime":
742
- value = ms(value);
743
- case "currentTime":
744
- case "playbackRate":
745
- for (let i = 0; i < target.animations.length; i++) {
746
- target.animations[i][key] = value;
747
- }
748
- return true;
749
- }
750
- return false;
751
- },
752
- };
753
- const selectFinished = (animation) => animation.finished;
754
-
755
- function stagger(duration = 0.1, { start = 0, from = 0, easing } = {}) {
756
- return (i, total) => {
757
- const fromIndex = isNumber(from) ? from : getFromIndex(from, total);
758
- const distance = Math.abs(fromIndex - i);
759
- let delay = duration * distance;
760
- if (easing) {
761
- const maxDelay = total * i;
762
- const easingFunction = getEasingFunction(easing);
763
- delay = easingFunction(delay / maxDelay) * maxDelay;
764
- }
765
- return start + delay;
766
- };
767
- }
768
- function getFromIndex(from, total) {
769
- if (from === "first") {
770
- return 0;
771
- }
772
- else {
773
- const lastIndex = total - 1;
774
- return from === "last" ? lastIndex : lastIndex / 2;
775
- }
776
- }
777
- function resolveOption(option, i, total) {
778
- return typeof option === "function"
779
- ? option(i, total)
780
- : option;
781
- }
782
-
783
- function animate(elements, keyframes, options = {}) {
784
- var _a;
785
- elements = resolveElements(elements);
786
- const numElements = elements.length;
787
- /**
788
- * Create and start new animations
789
- */
790
- const animationFactories = [];
791
- for (let i = 0; i < numElements; i++) {
792
- const element = elements[i];
793
- for (const key in keyframes) {
794
- const valueOptions = getOptions(options, key);
795
- valueOptions.delay = resolveOption(valueOptions.delay, i, numElements);
796
- const animation = animateStyle(element, key, keyframes[key], valueOptions);
797
- animationFactories.push(animation);
798
- }
799
- }
800
- return createAnimations(animationFactories,
801
- /**
802
- * TODO:
803
- * If easing is set to spring or glide, duration will be dynamically
804
- * generated. Ideally we would dynamically generate this from
805
- * animation.effect.getComputedTiming().duration but this isn't
806
- * supported in iOS13 or our number polyfill. Perhaps it's possible
807
- * to Proxy animations returned from animateStyle that has duration
808
- * as a getter.
809
- */
810
- (_a = options.duration) !== null && _a !== void 0 ? _a : defaults.duration);
811
- }
5
+ })(this, (function (exports) { 'use strict';
812
6
 
813
7
  /*! *****************************************************************************
814
8
  Copyright (c) Microsoft Corporation.
@@ -837,496 +31,18 @@
837
31
  return t;
838
32
  }
839
33
 
840
- var invariant = function () { };
841
- {
842
- invariant = function (check, message) {
843
- if (!check) {
844
- throw new Error(message);
845
- }
846
- };
847
- }
848
-
849
- function calcNextTime(current, next, prev, labels) {
850
- var _a;
851
- if (isNumber(next)) {
852
- return next;
853
- }
854
- else if (next.startsWith("-") || next.startsWith("+")) {
855
- return Math.max(0, current + parseFloat(next));
856
- }
857
- else if (next === "<") {
858
- return prev;
859
- }
860
- else {
861
- return (_a = labels.get(next)) !== null && _a !== void 0 ? _a : current;
862
- }
34
+ function animate(_a) {
35
+ var props = __rest(_a, []);
36
+ console.log(props);
863
37
  }
864
38
 
865
- function eraseKeyframes(sequence, startTime, endTime) {
866
- for (let i = 0; i < sequence.length; i++) {
867
- const keyframe = sequence[i];
868
- if (keyframe.at > startTime && keyframe.at < endTime) {
869
- removeItem(sequence, keyframe);
870
- // If we remove this item we have to push the pointer back one
871
- i--;
872
- }
873
- }
39
+ function test() {
40
+ console.log("test");
874
41
  }
875
- function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
876
- /**
877
- * Erase every existing value between currentTime and targetTime,
878
- * this will essentially splice this timeline into any currently
879
- * defined ones.
880
- */
881
- eraseKeyframes(sequence, startTime, endTime);
882
- for (let i = 0; i < keyframes.length; i++) {
883
- sequence.push({
884
- value: keyframes[i],
885
- at: mix(startTime, endTime, offset[i]),
886
- easing: getEasingForSegment(easing, i),
887
- });
888
- }
889
- }
890
-
891
- function compareByTime(a, b) {
892
- if (a.at === b.at) {
893
- return a.value === null ? 1 : -1;
894
- }
895
- else {
896
- return a.at - b.at;
897
- }
898
- }
899
-
900
- function timeline(definition, options = {}) {
901
- var _a, _b;
902
- const animationDefinitions = createAnimationsFromTimeline(definition, options);
903
- /**
904
- * Create and start animations
905
- */
906
- const animationFactories = animationDefinitions
907
- .map((definition) => animateStyle(...definition))
908
- .filter(Boolean);
909
- return createAnimations(animationFactories,
910
- // Get the duration from the first animation definition
911
- (_b = (_a = animationDefinitions[0]) === null || _a === void 0 ? void 0 : _a[3].duration) !== null && _b !== void 0 ? _b : defaults.duration);
912
- }
913
- function createAnimationsFromTimeline(definition, _a = {}) {
914
- var { defaultOptions = {} } = _a, timelineOptions = __rest(_a, ["defaultOptions"]);
915
- const animationDefinitions = [];
916
- const elementSequences = new Map();
917
- const elementCache = {};
918
- const timeLabels = new Map();
919
- let prevTime = 0;
920
- let currentTime = 0;
921
- let totalDuration = 0;
922
- /**
923
- * Build the timeline by mapping over the definition array and converting
924
- * the definitions into keyframes and offsets with absolute time values.
925
- * These will later get converted into relative offsets in a second pass.
926
- */
927
- for (let i = 0; i < definition.length; i++) {
928
- const [elementDefinition, keyframes, options = {}] = definition[i];
929
- /**
930
- * If a relative or absolute time value has been specified we need to resolve
931
- * it in relation to the currentTime.
932
- */
933
- if (options.at !== undefined) {
934
- currentTime = calcNextTime(currentTime, options.at, prevTime, timeLabels);
935
- }
936
- /**
937
- * Keep track of the maximum duration in this definition. This will be
938
- * applied to currentTime once the definition has been parsed.
939
- */
940
- let maxDuration = 0;
941
- /**
942
- * Find all the elements specified in the definition and parse value
943
- * keyframes from their timeline definitions.
944
- */
945
- const elements = resolveElements(elementDefinition, elementCache);
946
- const numElements = elements.length;
947
- for (let elementIndex = 0; elementIndex < numElements; elementIndex++) {
948
- const element = elements[elementIndex];
949
- const elementSequence = getElementSequence(element, elementSequences);
950
- for (const key in keyframes) {
951
- const valueSequence = getValueSequence(key, elementSequence);
952
- let valueKeyframes = keyframesList(keyframes[key]);
953
- const valueOptions = getOptions(options, key);
954
- let { duration = defaultOptions.duration || defaults.duration, easing = defaultOptions.easing || defaults.easing, } = valueOptions;
955
- if (isCustomEasing(easing)) {
956
- const valueIsTransform = isTransform(key);
957
- invariant(valueKeyframes.length === 2 || !valueIsTransform, "spring must be provided 2 keyframes within timeline");
958
- const custom = easing.createAnimation(valueKeyframes,
959
- // TODO We currently only support explicit keyframes
960
- // so this doesn't currently read from the DOM
961
- () => "0", valueIsTransform);
962
- easing = custom.easing;
963
- if (custom.keyframes !== undefined)
964
- valueKeyframes = custom.keyframes;
965
- if (custom.duration !== undefined)
966
- duration = custom.duration;
967
- }
968
- const delay = resolveOption(options.delay, elementIndex, numElements) || 0;
969
- const startTime = currentTime + delay;
970
- const targetTime = startTime + duration;
971
- /**
972
- *
973
- */
974
- let { offset = defaultOffset(valueKeyframes.length) } = valueOptions;
975
- /**
976
- * If there's only one offset of 0, fill in a second with length 1
977
- *
978
- * TODO: Ensure there's a test that covers this removal
979
- */
980
- if (offset.length === 1 && offset[0] === 0) {
981
- offset[1] = 1;
982
- }
983
- /**
984
- * Fill out if offset if fewer offsets than keyframes
985
- */
986
- const remainder = length - valueKeyframes.length;
987
- remainder > 0 && fillOffset(offset, remainder);
988
- /**
989
- * If only one value has been set, ie [1], push a null to the start of
990
- * the keyframe array. This will let us mark a keyframe at this point
991
- * that will later be hydrated with the previous value.
992
- */
993
- valueKeyframes.length === 1 && valueKeyframes.unshift(null);
994
- /**
995
- * Add keyframes, mapping offsets to absolute time.
996
- */
997
- addKeyframes(valueSequence, valueKeyframes, easing, offset, startTime, targetTime);
998
- maxDuration = Math.max(delay + duration, maxDuration);
999
- totalDuration = Math.max(targetTime, totalDuration);
1000
- }
1001
- }
1002
- prevTime = currentTime;
1003
- currentTime += maxDuration;
1004
- }
1005
- /**
1006
- * For every element and value combination create a new animation.
1007
- */
1008
- elementSequences.forEach((valueSequences, element) => {
1009
- for (const key in valueSequences) {
1010
- const valueSequence = valueSequences[key];
1011
- /**
1012
- * Arrange all the keyframes in ascending time order.
1013
- */
1014
- valueSequence.sort(compareByTime);
1015
- const keyframes = [];
1016
- const valueOffset = [];
1017
- const valueEasing = [];
1018
- /**
1019
- * For each keyframe, translate absolute times into
1020
- * relative offsets based on the total duration of the timeline.
1021
- */
1022
- for (let i = 0; i < valueSequence.length; i++) {
1023
- const { at, value, easing } = valueSequence[i];
1024
- keyframes.push(value);
1025
- valueOffset.push(progress(0, totalDuration, at));
1026
- valueEasing.push(easing || defaults.easing);
1027
- }
1028
- /**
1029
- * If the first keyframe doesn't land on offset: 0
1030
- * provide one by duplicating the initial keyframe. This ensures
1031
- * it snaps to the first keyframe when the animation starts.
1032
- */
1033
- if (valueOffset[0] !== 0) {
1034
- valueOffset.unshift(0);
1035
- keyframes.unshift(keyframes[0]);
1036
- valueEasing.unshift("linear");
1037
- }
1038
- /**
1039
- * If the last keyframe doesn't land on offset: 1
1040
- * provide one with a null wildcard value. This will ensure it
1041
- * stays static until the end of the animation.
1042
- */
1043
- if (valueOffset[valueOffset.length - 1] !== 1) {
1044
- valueOffset.push(1);
1045
- keyframes.push(null);
1046
- }
1047
- animationDefinitions.push([
1048
- element,
1049
- key,
1050
- keyframes,
1051
- Object.assign(Object.assign(Object.assign({}, defaultOptions), { duration: totalDuration, easing: valueEasing, offset: valueOffset }), timelineOptions),
1052
- ]);
1053
- }
1054
- });
1055
- return animationDefinitions;
1056
- }
1057
- function getElementSequence(element, sequences) {
1058
- !sequences.has(element) && sequences.set(element, {});
1059
- return sequences.get(element);
1060
- }
1061
- function getValueSequence(name, sequences) {
1062
- if (!sequences[name])
1063
- sequences[name] = [];
1064
- return sequences[name];
1065
- }
1066
-
1067
- /*
1068
- Convert velocity into velocity per second
1069
-
1070
- @param [number]: Unit per frame
1071
- @param [number]: Frame duration in ms
1072
- */
1073
- function velocityPerSecond(velocity, frameDuration) {
1074
- return frameDuration ? velocity * (1000 / frameDuration) : 0;
1075
- }
1076
-
1077
- function hasReachedTarget(origin, target, current) {
1078
- return ((origin < target && current >= target) ||
1079
- (origin > target && current <= target));
1080
- }
1081
-
1082
- const defaultStiffness = 100.0;
1083
- const defaultDamping = 10.0;
1084
- const defaultMass = 1.0;
1085
- const calcDampingRatio = (stiffness = defaultStiffness, damping = defaultDamping, mass = defaultMass) => damping / (2 * Math.sqrt(stiffness * mass));
1086
- const calcAngularFreq = (undampedFreq, dampingRatio) => undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
1087
- const createSpringGenerator = ({ stiffness = defaultStiffness, damping = defaultDamping, mass = defaultMass, from = 0, to = 1, velocity = 0.0, restSpeed = 2, restDistance = 0.5, } = {}) => {
1088
- velocity = velocity ? velocity / 1000 : 0.0;
1089
- const state = {
1090
- done: false,
1091
- value: from,
1092
- target: to,
1093
- velocity,
1094
- hasReachedTarget: false,
1095
- };
1096
- const dampingRatio = calcDampingRatio(stiffness, damping, mass);
1097
- const initialDelta = to - from;
1098
- const undampedAngularFreq = Math.sqrt(stiffness / mass) / 1000;
1099
- const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
1100
- let resolveSpring;
1101
- if (dampingRatio < 1) {
1102
- // Underdamped spring (bouncy)
1103
- resolveSpring = (t) => to -
1104
- Math.exp(-dampingRatio * undampedAngularFreq * t) *
1105
- (((-velocity + dampingRatio * undampedAngularFreq * initialDelta) /
1106
- angularFreq) *
1107
- Math.sin(angularFreq * t) +
1108
- initialDelta * Math.cos(angularFreq * t));
1109
- }
1110
- else {
1111
- // Critically damped spring
1112
- resolveSpring = (t) => to -
1113
- Math.exp(-undampedAngularFreq * t) *
1114
- (initialDelta + (velocity + undampedAngularFreq * initialDelta) * t);
1115
- }
1116
- return {
1117
- next: (t) => {
1118
- state.value = resolveSpring(t);
1119
- state.velocity =
1120
- t === 0 ? velocity : calcVelocity(resolveSpring, t, state.value);
1121
- const isBelowVelocityThreshold = Math.abs(state.velocity) <= restSpeed;
1122
- const isBelowDisplacementThreshold = Math.abs(to - state.value) <= restDistance;
1123
- state.done = isBelowVelocityThreshold && isBelowDisplacementThreshold;
1124
- state.hasReachedTarget = hasReachedTarget(from, to, state.value);
1125
- return state;
1126
- },
1127
- };
1128
- };
1129
- const sampleT = 5; // ms
1130
- function calcVelocity(resolveValue, t, current) {
1131
- const prevT = Math.max(t - sampleT, 0);
1132
- return velocityPerSecond(current - resolveValue(prevT), 5);
1133
- }
1134
-
1135
- const timeStep = 10;
1136
- const maxDuration = 10000;
1137
- function pregenerateKeyframes(generator) {
1138
- let overshootDuration = undefined;
1139
- let timestamp = timeStep;
1140
- let state = generator.next(0);
1141
- const keyframes = [state.value];
1142
- while (!state.done && timestamp < maxDuration) {
1143
- state = generator.next(timestamp);
1144
- keyframes.push(state.done ? state.target : state.value);
1145
- if (overshootDuration === undefined && state.hasReachedTarget) {
1146
- overshootDuration = timestamp;
1147
- }
1148
- timestamp += timeStep;
1149
- }
1150
- const duration = timestamp - timeStep;
1151
- /**
1152
- * If generating an animation that didn't actually move,
1153
- * generate a second keyframe so we have an origin and target.
1154
- */
1155
- if (keyframes.length === 1)
1156
- keyframes.push(state.value);
1157
- return {
1158
- keyframes,
1159
- duration: duration / 1000,
1160
- overshootDuration: (overshootDuration !== null && overshootDuration !== void 0 ? overshootDuration : duration) / 1000,
1161
- };
1162
- }
1163
-
1164
- function createGeneratorEasing(createGenerator) {
1165
- const keyframesCache = new WeakMap();
1166
- return (options = {}) => {
1167
- const generatorCache = new Map();
1168
- const getGenerator = (from = 0, to = 100, velocity = 0, isScale = false) => {
1169
- const key = `${from}-${to}-${velocity}-${isScale}`;
1170
- if (!generatorCache.has(key)) {
1171
- generatorCache.set(key, createGenerator(Object.assign({ from,
1172
- to,
1173
- velocity, restSpeed: isScale ? 0.05 : 2, restDistance: isScale ? 0.01 : 0.5 }, options)));
1174
- }
1175
- return generatorCache.get(key);
1176
- };
1177
- const getKeyframes = (generator) => {
1178
- if (!keyframesCache.has(generator)) {
1179
- keyframesCache.set(generator, pregenerateKeyframes(generator));
1180
- }
1181
- return keyframesCache.get(generator);
1182
- };
1183
- return {
1184
- createAnimation: (keyframes, getOrigin, canUseGenerator, name, data) => {
1185
- let settings;
1186
- let generator;
1187
- const numKeyframes = keyframes.length;
1188
- let shouldUseGenerator = canUseGenerator &&
1189
- numKeyframes <= 2 &&
1190
- keyframes.every(isNumberOrNull);
1191
- if (shouldUseGenerator) {
1192
- const prevAnimationState = name && data && data.prevGeneratorState[name];
1193
- const velocity = prevAnimationState &&
1194
- (numKeyframes === 1 ||
1195
- (numKeyframes === 2 && keyframes[0] === null))
1196
- ? prevAnimationState.velocity
1197
- : 0;
1198
- const target = keyframes[numKeyframes - 1];
1199
- const unresolvedOrigin = numKeyframes === 1 ? null : keyframes[0];
1200
- const origin = unresolvedOrigin === null
1201
- ? prevAnimationState
1202
- ? prevAnimationState.value
1203
- : parseFloat(getOrigin())
1204
- : unresolvedOrigin;
1205
- generator = getGenerator(origin, target, velocity, name === null || name === void 0 ? void 0 : name.includes("scale"));
1206
- const keyframesMetadata = getKeyframes(generator);
1207
- settings = Object.assign(Object.assign({}, keyframesMetadata), { easing: "linear" });
1208
- }
1209
- else {
1210
- generator = getGenerator(0, 100);
1211
- const keyframesMetadata = getKeyframes(generator);
1212
- settings = {
1213
- easing: "ease",
1214
- duration: keyframesMetadata.overshootDuration,
1215
- };
1216
- }
1217
- // TODO Add test for this
1218
- if (generator && data && name) {
1219
- data.generators[name] = generator;
1220
- }
1221
- return settings;
1222
- },
1223
- };
1224
- };
1225
- }
1226
- const isNumberOrNull = (value) => typeof value !== "string";
1227
-
1228
- const spring = createGeneratorEasing(createSpringGenerator);
1229
-
1230
- const createGlideGenerator = ({ from = 0, velocity = 0.0, power = 0.8, decay = 0.325, bounceDamping, bounceStiffness, changeTarget, min, max, restDistance = 0.5, restSpeed, }) => {
1231
- decay = ms(decay);
1232
- const state = {
1233
- value: from,
1234
- target: from,
1235
- velocity,
1236
- hasReachedTarget: false,
1237
- done: false,
1238
- };
1239
- const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
1240
- const nearestBoundary = (v) => {
1241
- if (min === undefined)
1242
- return max;
1243
- if (max === undefined)
1244
- return min;
1245
- return Math.abs(min - v) < Math.abs(max - v) ? min : max;
1246
- };
1247
- let amplitude = power * velocity;
1248
- const ideal = from + amplitude;
1249
- const target = changeTarget === undefined ? ideal : changeTarget(ideal);
1250
- state.target = target;
1251
- /**
1252
- * If the target has changed we need to re-calculate the amplitude, otherwise
1253
- * the animation will start from the wrong position.
1254
- */
1255
- if (target !== ideal)
1256
- amplitude = target - from;
1257
- const calcDelta = (t) => -amplitude * Math.exp(-t / decay);
1258
- const calcLatest = (t) => target + calcDelta(t);
1259
- const applyFriction = (t) => {
1260
- const delta = calcDelta(t);
1261
- const latest = calcLatest(t);
1262
- state.done = Math.abs(delta) <= restDistance;
1263
- state.value = state.done ? target : latest;
1264
- state.velocity =
1265
- t === 0 ? velocity : calcVelocity(calcLatest, t, state.value);
1266
- };
1267
- /**
1268
- * Ideally this would resolve for t in a stateless way, we could
1269
- * do that by always precalculating the animation but as we know
1270
- * this will be done anyway we can assume that spring will
1271
- * be discovered during that.
1272
- */
1273
- let timeReachedBoundary;
1274
- let spring;
1275
- const checkCatchBoundary = (t) => {
1276
- if (!isOutOfBounds(state.value))
1277
- return;
1278
- timeReachedBoundary = t;
1279
- spring = createSpringGenerator({
1280
- from: state.value,
1281
- to: nearestBoundary(state.value),
1282
- velocity: state.velocity,
1283
- damping: bounceDamping,
1284
- stiffness: bounceStiffness,
1285
- restDistance,
1286
- restSpeed,
1287
- });
1288
- };
1289
- checkCatchBoundary(0);
1290
- return {
1291
- next: (t) => {
1292
- /**
1293
- * We need to resolve the friction to figure out if we need a
1294
- * spring but we don't want to do this twice per frame. So here
1295
- * we flag if we updated for this frame and later if we did
1296
- * we can skip doing it again.
1297
- */
1298
- let hasUpdatedFrame = false;
1299
- if (!spring && timeReachedBoundary === undefined) {
1300
- hasUpdatedFrame = true;
1301
- applyFriction(t);
1302
- checkCatchBoundary(t);
1303
- }
1304
- /**
1305
- * If we have a spring and the provided t is beyond the moment the friction
1306
- * animation crossed the min/max boundary, use the spring.
1307
- */
1308
- if (timeReachedBoundary !== undefined && t > timeReachedBoundary) {
1309
- state.hasReachedTarget = true;
1310
- return spring.next(t - timeReachedBoundary);
1311
- }
1312
- else {
1313
- state.hasReachedTarget = false;
1314
- !hasUpdatedFrame && applyFriction(t);
1315
- return state;
1316
- }
1317
- },
1318
- };
1319
- };
1320
-
1321
- const glide = createGeneratorEasing(createGlideGenerator);
1322
42
 
1323
43
  exports.animate = animate;
1324
- exports.animateStyle = animateStyle;
1325
- exports.glide = glide;
1326
- exports.spring = spring;
1327
- exports.stagger = stagger;
1328
- exports.timeline = timeline;
44
+ exports.test = test;
1329
45
 
1330
46
  Object.defineProperty(exports, '__esModule', { value: true });
1331
47
 
1332
- })));
48
+ }));