react-ui-animate 2.0.0-rc.7 → 3.0.0-rc.0

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 (222) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/LICENSE +21 -21
  3. package/README.md +115 -115
  4. package/dist/animation/animationType.d.ts +15 -15
  5. package/dist/animation/core/animation/Animation.d.ts +16 -0
  6. package/dist/animation/core/animation/FluidValue.d.ts +21 -0
  7. package/dist/animation/core/animation/RequestAnimationFrame.d.ts +8 -0
  8. package/dist/animation/core/animation/SpringAnimation.d.ts +41 -0
  9. package/dist/animation/core/animation/TimingAnimation.d.ts +35 -0
  10. package/dist/animation/core/animation/TransitionValue.d.ts +21 -0
  11. package/dist/animation/core/controllers/Animation.d.ts +16 -0
  12. package/dist/animation/core/controllers/FluidValue.d.ts +32 -0
  13. package/dist/animation/core/controllers/RequestAnimationFrame.d.ts +8 -0
  14. package/dist/animation/core/controllers/SpringAnimation.d.ts +41 -0
  15. package/dist/animation/core/controllers/TimingAnimation.d.ts +35 -0
  16. package/dist/animation/core/easing/Bezier.d.ts +8 -0
  17. package/dist/animation/core/easing/Easing.d.ts +40 -0
  18. package/dist/animation/core/helpers/camelCaseToKebabCase.d.ts +8 -0
  19. package/dist/animation/core/helpers/camelToDash.d.ts +7 -0
  20. package/dist/animation/core/helpers/canInterpolate.d.ts +11 -0
  21. package/dist/animation/core/helpers/getAnimatableObject.d.ts +22 -0
  22. package/dist/animation/core/helpers/getCleanProps.d.ts +10 -0
  23. package/dist/animation/core/helpers/getCssValue.d.ts +8 -0
  24. package/dist/animation/core/helpers/getNonAnimatableStyle.d.ts +6 -0
  25. package/dist/animation/core/helpers/index.d.ts +5 -0
  26. package/dist/animation/core/helpers/isDefined.d.ts +12 -0
  27. package/dist/animation/core/helpers/isFluidValue.d.ts +6 -0
  28. package/dist/animation/core/index.d.ts +11 -0
  29. package/dist/animation/core/interpolation/Colors.d.ts +25 -0
  30. package/dist/animation/core/interpolation/Interpolation.d.ts +80 -0
  31. package/dist/animation/core/interpolation/__tests__/Colors.test.d.ts +1 -0
  32. package/dist/animation/core/react/Tags.d.ts +3 -0
  33. package/dist/animation/core/react/TransformStyles.d.ts +8 -0
  34. package/dist/animation/core/react/animated.d.ts +29 -0
  35. package/dist/animation/core/react/combineRefs.d.ts +2 -0
  36. package/dist/animation/core/react/fluid.d.ts +6 -0
  37. package/dist/animation/core/react/functions/camelToDash.d.ts +7 -0
  38. package/dist/animation/core/react/functions/getAnimatableObject.d.ts +22 -0
  39. package/dist/animation/core/react/functions/getCleanProps.d.ts +4 -0
  40. package/dist/animation/core/react/functions/getCssValue.d.ts +8 -0
  41. package/dist/animation/core/react/functions/getNonAnimatableStyle.d.ts +6 -0
  42. package/dist/animation/core/react/functions/index.d.ts +7 -0
  43. package/dist/animation/core/react/functions/isDefined.d.ts +6 -0
  44. package/dist/animation/core/react/functions/isTransitionValue.d.ts +6 -0
  45. package/dist/animation/core/react/helpers/camelToDash.d.ts +7 -0
  46. package/dist/animation/core/react/helpers/canInterpolate.d.ts +7 -0
  47. package/dist/animation/core/react/helpers/getAnimatableObject.d.ts +22 -0
  48. package/dist/animation/core/react/helpers/getCleanProps.d.ts +4 -0
  49. package/dist/animation/core/react/helpers/getCssValue.d.ts +8 -0
  50. package/dist/animation/core/react/helpers/getNonAnimatableStyle.d.ts +6 -0
  51. package/dist/animation/core/react/helpers/index.d.ts +7 -0
  52. package/dist/animation/core/react/helpers/isDefined.d.ts +6 -0
  53. package/dist/animation/core/react/helpers/isFluidValue.d.ts +6 -0
  54. package/dist/animation/core/react/helpers/isTransitionValue.d.ts +6 -0
  55. package/dist/animation/core/react/makeFluid.d.ts +30 -0
  56. package/dist/animation/core/react/transforms.d.ts +6 -0
  57. package/dist/animation/core/react/useFluidValue.d.ts +9 -0
  58. package/dist/animation/core/react/useMount.d.ts +20 -0
  59. package/dist/animation/core/react/useMounts.d.ts +26 -0
  60. package/dist/animation/core/react/useTransition.d.ts +9 -0
  61. package/dist/animation/core/react/useTransitions.d.ts +11 -0
  62. package/dist/animation/core/types/animation.d.ts +54 -0
  63. package/dist/animation/core/types/common.d.ts +4 -0
  64. package/dist/animation/core/types/fluid.d.ts +19 -0
  65. package/dist/animation/core/types/index.d.ts +2 -0
  66. package/dist/animation/getInitialConfig.d.ts +3 -3
  67. package/dist/animation/index.d.ts +6 -6
  68. package/dist/animation/interpolation.d.ts +21 -21
  69. package/dist/animation/lib/animationType.d.ts +15 -0
  70. package/dist/animation/lib/getInitialConfig.d.ts +3 -0
  71. package/dist/animation/lib/index.d.ts +5 -0
  72. package/dist/animation/lib/interpolation.d.ts +20 -0
  73. package/dist/animation/lib/modules/AnimatedBlock.d.ts +8 -0
  74. package/dist/animation/lib/modules/AnimatedImage.d.ts +8 -0
  75. package/dist/animation/lib/modules/AnimatedInline.d.ts +8 -0
  76. package/dist/animation/lib/modules/MountedBlock.d.ts +29 -0
  77. package/dist/animation/lib/modules/ScrollableBlock.d.ts +22 -0
  78. package/dist/animation/lib/modules/TransitionBlock.d.ts +18 -0
  79. package/dist/animation/lib/modules/index.d.ts +6 -0
  80. package/dist/animation/lib/useAnimatedValue.d.ts +17 -0
  81. package/dist/animation/lib/useMountedValue.d.ts +14 -0
  82. package/dist/animation/modules/AnimatedBlock.d.ts +8 -8
  83. package/dist/animation/modules/AnimatedImage.d.ts +8 -8
  84. package/dist/animation/modules/AnimatedInline.d.ts +8 -8
  85. package/dist/animation/modules/MountedBlock.d.ts +29 -18
  86. package/dist/animation/modules/ScrollableBlock.d.ts +21 -21
  87. package/dist/animation/modules/TransitionBlock.d.ts +17 -17
  88. package/dist/animation/modules/index.d.ts +6 -6
  89. package/dist/animation/useAnimatedValue.d.ts +22 -22
  90. package/dist/animation/useMountedValue.d.ts +15 -15
  91. package/dist/gestures/controllers/DragGesture.d.ts +17 -17
  92. package/dist/gestures/controllers/Gesture.d.ts +20 -20
  93. package/dist/gestures/controllers/MouseMoveGesture.d.ts +13 -13
  94. package/dist/gestures/controllers/ScrollGesture.d.ts +14 -14
  95. package/dist/gestures/controllers/WheelGesture.d.ts +15 -15
  96. package/dist/gestures/controllers/index.d.ts +4 -4
  97. package/dist/gestures/eventAttacher.d.ts +11 -11
  98. package/dist/gestures/helpers/eventAttacher.d.ts +11 -0
  99. package/dist/gestures/helpers/index.d.ts +1 -0
  100. package/dist/gestures/helpers/math.d.ts +34 -0
  101. package/dist/gestures/helpers/withDefault.d.ts +4 -0
  102. package/dist/gestures/hooks/index.d.ts +5 -5
  103. package/dist/gestures/hooks/useDrag.d.ts +4 -4
  104. package/dist/gestures/hooks/useGesture.d.ts +9 -9
  105. package/dist/gestures/hooks/useMouseMove.d.ts +4 -4
  106. package/dist/gestures/hooks/useRecognizer.d.ts +10 -10
  107. package/dist/gestures/hooks/useScroll.d.ts +4 -4
  108. package/dist/gestures/hooks/useWheel.d.ts +4 -4
  109. package/dist/gestures/index.d.ts +2 -2
  110. package/dist/gestures/math.d.ts +34 -34
  111. package/dist/gestures/types.d.ts +51 -51
  112. package/dist/gestures/withDefault.d.ts +4 -4
  113. package/dist/hooks/index.d.ts +3 -3
  114. package/dist/hooks/useMeasure.d.ts +14 -14
  115. package/dist/hooks/useOutsideClick.d.ts +2 -2
  116. package/dist/hooks/useWindowDimension.d.ts +9 -9
  117. package/dist/index.d.ts +9 -5
  118. package/dist/index.js +2758 -1052
  119. package/dist/index.js.map +1 -1
  120. package/dist/utils/delay.d.ts +5 -5
  121. package/dist/utils/index.d.ts +1 -2
  122. package/dist/utils/isDefined.d.ts +1 -1
  123. package/ecosystem.config.js +12 -0
  124. package/example/README.md +46 -0
  125. package/example/package-lock.json +19597 -0
  126. package/example/package.json +45 -0
  127. package/example/public/favicon.ico +0 -0
  128. package/example/public/index.html +20 -0
  129. package/example/public/logo192.png +0 -0
  130. package/example/public/logo512.png +0 -0
  131. package/example/public/manifest.json +25 -0
  132. package/example/public/robots.txt +3 -0
  133. package/example/src/App.tsx +41 -0
  134. package/example/src/components/Draggable.tsx +46 -0
  135. package/example/src/components/Gestures.tsx +151 -0
  136. package/example/src/components/Interpolation.tsx +21 -0
  137. package/example/src/components/Loop.tsx +48 -0
  138. package/example/src/components/MountedBlock.tsx +25 -0
  139. package/example/src/components/MouseMove.tsx +59 -0
  140. package/example/src/components/MultistageTransition.tsx +34 -0
  141. package/example/src/components/Scroll.tsx +39 -0
  142. package/example/src/components/ScrollableBlock.tsx +27 -0
  143. package/example/src/components/SnapTo.tsx +55 -0
  144. package/example/src/components/TransitionBlock.tsx +37 -0
  145. package/example/src/components/Wheel.tsx +39 -0
  146. package/example/src/components/index.ts +18 -0
  147. package/example/src/components/svgLine.tsx +48 -0
  148. package/example/src/components/useAnimatedValue.tsx +57 -0
  149. package/example/src/components/useMountedValue.tsx +62 -0
  150. package/example/src/index.css +8 -0
  151. package/example/src/index.tsx +16 -0
  152. package/example/tsconfig.json +26 -0
  153. package/package.json +48 -48
  154. package/{rollup.config.js → rollup.config.mjs} +18 -18
  155. package/src/animation/core/controllers/Animation.ts +27 -0
  156. package/src/animation/core/controllers/FluidValue.ts +97 -0
  157. package/src/animation/core/controllers/RequestAnimationFrame.ts +13 -0
  158. package/src/animation/core/controllers/SpringAnimation.ts +218 -0
  159. package/src/animation/core/controllers/TimingAnimation.ts +152 -0
  160. package/src/animation/core/easing/Bezier.ts +146 -0
  161. package/src/animation/core/easing/Easing.ts +132 -0
  162. package/src/animation/core/helpers/camelCaseToKebabCase.ts +10 -0
  163. package/src/animation/core/helpers/getCleanProps.ts +16 -0
  164. package/src/animation/core/helpers/getCssValue.ts +60 -0
  165. package/src/animation/core/helpers/index.ts +5 -0
  166. package/src/animation/core/helpers/isDefined.ts +14 -0
  167. package/src/animation/core/helpers/isFluidValue.ts +11 -0
  168. package/src/animation/core/index.ts +16 -0
  169. package/src/animation/core/interpolation/Colors.ts +232 -0
  170. package/src/animation/core/interpolation/Interpolation.ts +395 -0
  171. package/src/animation/core/interpolation/__tests__/Colors.test.tsx +35 -0
  172. package/src/animation/core/react/fluid.ts +197 -0
  173. package/src/animation/core/react/makeFluid.ts +294 -0
  174. package/src/animation/core/react/transforms.ts +90 -0
  175. package/src/animation/core/react/useFluidValue.ts +43 -0
  176. package/src/animation/core/react/useMount.ts +58 -0
  177. package/src/animation/core/types/animation.d.ts +56 -0
  178. package/src/animation/core/types/common.d.ts +4 -0
  179. package/src/animation/core/types/fluid.d.ts +38 -0
  180. package/src/animation/{animationType.ts → lib/animationType.ts} +17 -17
  181. package/src/animation/{getInitialConfig.ts → lib/getInitialConfig.ts} +61 -61
  182. package/src/animation/lib/index.ts +12 -0
  183. package/src/animation/{interpolation.ts → lib/interpolation.ts} +47 -48
  184. package/src/animation/{modules → lib/modules}/AnimatedBlock.ts +8 -8
  185. package/src/animation/{modules → lib/modules}/AnimatedImage.ts +8 -8
  186. package/src/animation/{modules → lib/modules}/AnimatedInline.ts +8 -8
  187. package/src/animation/lib/modules/MountedBlock.tsx +51 -0
  188. package/src/animation/{modules → lib/modules}/ScrollableBlock.tsx +68 -69
  189. package/src/animation/{modules → lib/modules}/TransitionBlock.tsx +28 -29
  190. package/src/animation/{modules → lib/modules}/index.ts +6 -6
  191. package/src/animation/{useAnimatedValue.ts → lib/useAnimatedValue.ts} +60 -71
  192. package/src/animation/{useMountedValue.ts → lib/useMountedValue.ts} +18 -19
  193. package/src/gestures/controllers/DragGesture.ts +178 -177
  194. package/src/gestures/controllers/Gesture.ts +54 -54
  195. package/src/gestures/controllers/MouseMoveGesture.ts +111 -111
  196. package/src/gestures/controllers/ScrollGesture.ts +107 -107
  197. package/src/gestures/controllers/WheelGesture.ts +123 -123
  198. package/src/gestures/controllers/index.ts +4 -4
  199. package/src/gestures/{eventAttacher.ts → helpers/eventAttacher.ts} +67 -67
  200. package/src/gestures/helpers/index.ts +1 -0
  201. package/src/gestures/{math.ts → helpers/math.ts} +120 -120
  202. package/src/gestures/{withDefault.ts → helpers/withDefault.ts} +3 -3
  203. package/src/gestures/hooks/index.ts +5 -5
  204. package/src/gestures/hooks/useDrag.ts +14 -14
  205. package/src/gestures/hooks/useGesture.ts +38 -38
  206. package/src/gestures/hooks/useMouseMove.ts +11 -11
  207. package/src/gestures/hooks/useRecognizer.ts +59 -59
  208. package/src/gestures/hooks/useScroll.ts +11 -11
  209. package/src/gestures/hooks/useWheel.ts +11 -11
  210. package/src/gestures/{types.ts → types/index.d.ts} +49 -49
  211. package/src/hooks/index.ts +3 -3
  212. package/src/hooks/useMeasure.ts +132 -133
  213. package/src/hooks/useOutsideClick.ts +36 -36
  214. package/src/hooks/useWindowDimension.ts +58 -59
  215. package/src/index.ts +42 -5
  216. package/src/utils/delay.ts +9 -9
  217. package/src/utils/index.ts +1 -2
  218. package/tsconfig.json +24 -25
  219. package/src/animation/index.ts +0 -10
  220. package/src/animation/modules/MountedBlock.tsx +0 -25
  221. package/src/gestures/index.ts +0 -2
  222. package/src/utils/isDefined.ts +0 -4
@@ -0,0 +1,218 @@
1
+ import { Animation } from './Animation';
2
+ import {
3
+ RequestAnimationFrame,
4
+ CancelAnimationFrame,
5
+ } from './RequestAnimationFrame';
6
+
7
+ import type { FluidValueConfig, ResultType } from '../types/animation';
8
+
9
+ /**
10
+ * Class implementing spring based animation
11
+ */
12
+ export class SpringAnimation extends Animation {
13
+ _overshootClamping: boolean;
14
+ _restDisplacementThreshold: number;
15
+ _restSpeedThreshold: number;
16
+ _initialVelocity?: number;
17
+ _lastVelocity: number;
18
+ _startPosition: number;
19
+ _lastPosition: number;
20
+ _position: number;
21
+ _fromValue: number;
22
+ _toValue: any;
23
+ _mass: number;
24
+ _tension: number;
25
+ _friction: number;
26
+ _lastTime: number;
27
+ _onFrame: (value: number) => void;
28
+ _animationFrame: any;
29
+ _timeout: any;
30
+
31
+ // Modifiers
32
+ _delay: number;
33
+ _onRest?: (value: ResultType) => void;
34
+ _onChange?: (value: number) => void;
35
+
36
+ constructor({
37
+ initialPosition,
38
+ config,
39
+ }: {
40
+ initialPosition: number;
41
+ config?: Omit<FluidValueConfig, 'duration' | 'easing'>;
42
+ }) {
43
+ super();
44
+
45
+ this._overshootClamping = false;
46
+ this._initialVelocity = 0;
47
+ this._lastVelocity = 0;
48
+ this._startPosition = initialPosition;
49
+ this._position = this._startPosition;
50
+
51
+ this._restDisplacementThreshold = config?.restDistance ?? 0.001;
52
+ this._restSpeedThreshold = config?.restDistance ?? 0.001;
53
+ this._mass = config?.mass ?? 1;
54
+ this._tension = config?.tension ?? 170;
55
+ this._friction = config?.friction ?? 26;
56
+ this._delay = config?.delay ?? 0;
57
+
58
+ this._onRest = config?.onRest;
59
+ this._onChange = config?.onChange;
60
+ }
61
+
62
+ onChange(value: number) {
63
+ this._onFrame(value);
64
+
65
+ if (this._lastPosition !== value) {
66
+ if (this._onChange) {
67
+ this._onChange(value);
68
+ }
69
+ }
70
+
71
+ this._lastPosition = value;
72
+ }
73
+
74
+ onUpdate() {
75
+ var now = Date.now();
76
+
77
+ const deltaTime = Math.min(now - this._lastTime, 64);
78
+ this._lastTime = now;
79
+
80
+ const c = this._friction;
81
+ const m = this._mass;
82
+ const k = this._tension;
83
+
84
+ const v0 = -this._lastVelocity;
85
+ const x0 = this._toValue - this._position;
86
+
87
+ const zeta = c / (2 * Math.sqrt(k * m)); // damping ratio
88
+ const omega0 = Math.sqrt(k / m); // undamped angular frequency of the oscillator (rad/ms)
89
+ const omega1 = omega0 * Math.sqrt(1 - zeta ** 2); // exponential decay
90
+
91
+ const t = deltaTime / 1000;
92
+
93
+ const sin1 = Math.sin(omega1 * t);
94
+ const cos1 = Math.cos(omega1 * t);
95
+
96
+ // under damped
97
+ const underDampedEnvelope = Math.exp(-zeta * omega0 * t);
98
+ const underDampedFrag1 =
99
+ underDampedEnvelope *
100
+ (sin1 * ((v0 + zeta * omega0 * x0) / omega1) + x0 * cos1);
101
+
102
+ const underDampedPosition = this._toValue - underDampedFrag1;
103
+ // This looks crazy -- it's actually just the derivative of the oscillation function
104
+ const underDampedVelocity =
105
+ zeta * omega0 * underDampedFrag1 -
106
+ underDampedEnvelope *
107
+ (cos1 * (v0 + zeta * omega0 * x0) - omega1 * x0 * sin1);
108
+
109
+ // critically damped
110
+ const criticallyDampedEnvelope = Math.exp(-omega0 * t);
111
+ const criticallyDampedPosition =
112
+ this._toValue - criticallyDampedEnvelope * (x0 + (v0 + omega0 * x0) * t);
113
+
114
+ const criticallyDampedVelocity =
115
+ criticallyDampedEnvelope *
116
+ (v0 * (t * omega0 - 1) + t * x0 * omega0 * omega0);
117
+
118
+ this.onChange(this._position);
119
+
120
+ const isOvershooting = () => {
121
+ if (this._overshootClamping && this._tension !== 0) {
122
+ return this._position < this._toValue
123
+ ? this._position > this._toValue
124
+ : this._position < this._toValue;
125
+ } else {
126
+ return false;
127
+ }
128
+ };
129
+
130
+ const isVelocity = Math.abs(this._lastVelocity) < this._restSpeedThreshold;
131
+ const isDisplacement =
132
+ this._tension === 0 ||
133
+ Math.abs(this._toValue - this._position) <
134
+ this._restDisplacementThreshold;
135
+
136
+ if (zeta < 1) {
137
+ this._position = underDampedPosition;
138
+ this._lastVelocity = underDampedVelocity;
139
+ } else {
140
+ this._position = criticallyDampedPosition;
141
+ this._lastVelocity = criticallyDampedVelocity;
142
+ }
143
+
144
+ if (isOvershooting() || (isVelocity && isDisplacement)) {
145
+ if (this._tension !== 0) {
146
+ this._lastVelocity = 0;
147
+ this._position = this._toValue;
148
+
149
+ this.onChange(this._position);
150
+ }
151
+ // clear lastTimestamp to avoid using stale value by the next spring animation that starts after this one
152
+ this._lastTime = 0;
153
+
154
+ this._debounceOnEnd({ finished: true, value: this._toValue });
155
+
156
+ return;
157
+ }
158
+
159
+ this._animationFrame = RequestAnimationFrame.current(
160
+ this.onUpdate.bind(this)
161
+ );
162
+ }
163
+
164
+ stop() {
165
+ this._active = false;
166
+ clearTimeout(this._timeout);
167
+ CancelAnimationFrame.current(this._animationFrame);
168
+ this._debounceOnEnd({ finished: false, value: this._position });
169
+ }
170
+
171
+ // Set value
172
+ set(toValue: number) {
173
+ this.stop();
174
+ this._position = toValue;
175
+ this._lastTime = 0;
176
+ this._lastVelocity = 0;
177
+ this.onChange(toValue);
178
+ }
179
+
180
+ start({
181
+ toValue,
182
+ onFrame,
183
+ previousAnimation,
184
+ onEnd,
185
+ }: {
186
+ toValue: number;
187
+ onFrame: (value: number) => void;
188
+ previousAnimation?: SpringAnimation;
189
+ onEnd?: (result: ResultType) => void;
190
+ }) {
191
+ const onStart: any = () => {
192
+ this._onFrame = onFrame;
193
+ this._active = true;
194
+ this._toValue = toValue;
195
+ this._onEnd = onEnd;
196
+
197
+ const now = Date.now();
198
+
199
+ if (previousAnimation instanceof SpringAnimation) {
200
+ this._lastVelocity =
201
+ previousAnimation._lastVelocity || this._lastVelocity || 0;
202
+ this._lastTime = previousAnimation._lastTime || now;
203
+ } else {
204
+ this._lastTime = now;
205
+ }
206
+
207
+ this._animationFrame = RequestAnimationFrame.current(
208
+ this.onUpdate.bind(this)
209
+ );
210
+ };
211
+
212
+ if (this._delay !== 0) {
213
+ this._timeout = setTimeout(() => onStart(), this._delay);
214
+ } else {
215
+ onStart();
216
+ }
217
+ }
218
+ }
@@ -0,0 +1,152 @@
1
+ import { Animation } from './Animation';
2
+ import {
3
+ RequestAnimationFrame,
4
+ CancelAnimationFrame,
5
+ } from './RequestAnimationFrame';
6
+ import { Easing } from '../easing/Easing';
7
+
8
+ import type { FluidValueConfig, ResultType } from '../types/animation';
9
+
10
+ /**
11
+ * Class implementing timing based animation
12
+ */
13
+ export class TimingAnimation extends Animation {
14
+ _startTime: number;
15
+ _fromValue: number;
16
+ _toValue: any;
17
+ _duration: number;
18
+ _easing: (value: number) => number;
19
+ _onFrame: (value: number) => void;
20
+ _animationFrame: any;
21
+ _timeout: any;
22
+ _lastPosition: number;
23
+ _position: number;
24
+
25
+ // Modifiers
26
+ _delay: number;
27
+ _tempDuration: number;
28
+ _onRest?: (value: ResultType) => void;
29
+ _onChange?: (value: number) => void;
30
+
31
+ constructor({
32
+ initialPosition,
33
+ config,
34
+ }: {
35
+ initialPosition: number;
36
+ config?: Omit<FluidValueConfig, 'mass' | 'friction' | 'tension'>;
37
+ }) {
38
+ super();
39
+
40
+ this._fromValue = initialPosition;
41
+ this._position = this._fromValue;
42
+ this._easing = config?.easing ?? Easing.linear;
43
+ this._duration = config?.duration ?? 500;
44
+ this._tempDuration = this._duration;
45
+
46
+ // Modifiers
47
+ // here immediate acts like duration: 0
48
+ if (config?.immediate) {
49
+ this._duration = 0;
50
+ }
51
+
52
+ this._delay = config?.delay ?? 0;
53
+ this._onRest = config?.onRest;
54
+ this._onChange = config?.onChange;
55
+ }
56
+
57
+ onChange(value: number) {
58
+ this._onFrame(value);
59
+
60
+ if (this._lastPosition !== value) {
61
+ if (this._onChange) {
62
+ this._onChange(value);
63
+ }
64
+ }
65
+
66
+ this._lastPosition = value;
67
+ }
68
+
69
+ onUpdate() {
70
+ const now = Date.now();
71
+
72
+ const runTime = now - this._startTime;
73
+
74
+ if (runTime >= this._duration) {
75
+ this._startTime = 0;
76
+ this._position = this._toValue;
77
+
78
+ this.onChange(this._position);
79
+
80
+ this._debounceOnEnd({ finished: true, value: this._position });
81
+ return;
82
+ }
83
+
84
+ const progress = this._easing(runTime / this._duration);
85
+
86
+ this._position =
87
+ this._fromValue + (this._toValue - this._fromValue) * progress;
88
+
89
+ this.onChange(this._position);
90
+
91
+ this._animationFrame = RequestAnimationFrame.current(
92
+ this.onUpdate.bind(this)
93
+ );
94
+ }
95
+
96
+ stop() {
97
+ this._active = false;
98
+ clearTimeout(this._timeout);
99
+ CancelAnimationFrame.current(this._animationFrame);
100
+ this._debounceOnEnd({ finished: false, value: this._position });
101
+ }
102
+
103
+ // Set value
104
+ set(toValue: number) {
105
+ this.stop();
106
+ this._position = toValue;
107
+ this.onChange(toValue);
108
+ }
109
+
110
+ start({
111
+ toValue,
112
+ onFrame,
113
+ previousAnimation,
114
+ onEnd,
115
+ }: {
116
+ toValue: number;
117
+ onFrame: (value: number) => void;
118
+ previousAnimation?: TimingAnimation;
119
+ onEnd?: (result: ResultType) => void;
120
+ }) {
121
+ const onStart: any = () => {
122
+ this._onFrame = onFrame;
123
+ this._active = true;
124
+ this._onEnd = onEnd;
125
+ this._toValue = toValue;
126
+
127
+ if (
128
+ previousAnimation &&
129
+ previousAnimation instanceof TimingAnimation &&
130
+ previousAnimation._toValue === toValue &&
131
+ previousAnimation._startTime
132
+ ) {
133
+ this._startTime = previousAnimation._startTime;
134
+ this._fromValue = previousAnimation._fromValue;
135
+ } else {
136
+ const now = Date.now();
137
+ this._startTime = now;
138
+ this._fromValue = this._position;
139
+ }
140
+
141
+ this._animationFrame = RequestAnimationFrame.current(
142
+ this.onUpdate.bind(this)
143
+ );
144
+ };
145
+
146
+ if (this._delay !== 0) {
147
+ this._timeout = setTimeout(() => onStart(), this._delay);
148
+ } else {
149
+ onStart();
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * https://github.com/gre/bezier-easing
3
+ * BezierEasing - use bezier curve for transition easing function
4
+ * by Gaëtan Renaudeau 2014 - 2015 – MIT License
5
+ */
6
+
7
+ // These values are established by empiricism with tests (tradeoff: performance VS precision)
8
+ var NEWTON_ITERATIONS = 4;
9
+ var NEWTON_MIN_SLOPE = 0.001;
10
+ var SUBDIVISION_PRECISION = 0.0000001;
11
+ var SUBDIVISION_MAX_ITERATIONS = 10;
12
+
13
+ var kSplineTableSize = 11;
14
+ var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
15
+
16
+ var float32ArraySupported = typeof Float32Array === "function";
17
+
18
+ function A(aA1: number, aA2: number) {
19
+ return 1.0 - 3.0 * aA2 + 3.0 * aA1;
20
+ }
21
+ function B(aA1: number, aA2: number) {
22
+ return 3.0 * aA2 - 6.0 * aA1;
23
+ }
24
+ function C(aA1: number) {
25
+ return 3.0 * aA1;
26
+ }
27
+
28
+ // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
29
+ function calcBezier(aT: number, aA1: number, aA2: number) {
30
+ return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
31
+ }
32
+
33
+ // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
34
+ function getSlope(aT: number, aA1: number, aA2: number) {
35
+ return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
36
+ }
37
+
38
+ function binarySubdivide(
39
+ aX: number,
40
+ aA: number,
41
+ aB: number,
42
+ mX1: number,
43
+ mX2: number
44
+ ) {
45
+ var currentX,
46
+ currentT,
47
+ i = 0;
48
+ do {
49
+ currentT = aA + (aB - aA) / 2.0;
50
+ currentX = calcBezier(currentT, mX1, mX2) - aX;
51
+ if (currentX > 0.0) {
52
+ aB = currentT;
53
+ } else {
54
+ aA = currentT;
55
+ }
56
+ } while (
57
+ Math.abs(currentX) > SUBDIVISION_PRECISION &&
58
+ ++i < SUBDIVISION_MAX_ITERATIONS
59
+ );
60
+ return currentT;
61
+ }
62
+
63
+ function newtonRaphsonIterate(
64
+ aX: number,
65
+ aGuessT: number,
66
+ mX1: number,
67
+ mX2: number
68
+ ) {
69
+ for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
70
+ var currentSlope = getSlope(aGuessT, mX1, mX2);
71
+ if (currentSlope === 0.0) {
72
+ return aGuessT;
73
+ }
74
+ var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
75
+ aGuessT -= currentX / currentSlope;
76
+ }
77
+ return aGuessT;
78
+ }
79
+
80
+ function LinearEasing(x: number) {
81
+ return x;
82
+ }
83
+
84
+ function bezier(mX1: number, mY1: number, mX2: number, mY2: number) {
85
+ if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
86
+ throw new Error("bezier x values must be in [0, 1] range");
87
+ }
88
+
89
+ if (mX1 === mY1 && mX2 === mY2) {
90
+ return LinearEasing;
91
+ }
92
+
93
+ // Precompute samples table
94
+ var sampleValues = float32ArraySupported
95
+ ? new Float32Array(kSplineTableSize)
96
+ : new Array(kSplineTableSize);
97
+ for (var i = 0; i < kSplineTableSize; ++i) {
98
+ sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
99
+ }
100
+
101
+ function getTForX(aX: number) {
102
+ var intervalStart = 0.0;
103
+ var currentSample = 1;
104
+ var lastSample = kSplineTableSize - 1;
105
+
106
+ for (
107
+ ;
108
+ currentSample !== lastSample && sampleValues[currentSample] <= aX;
109
+ ++currentSample
110
+ ) {
111
+ intervalStart += kSampleStepSize;
112
+ }
113
+ --currentSample;
114
+
115
+ // Interpolate to provide an initial guess for t
116
+ var dist =
117
+ (aX - sampleValues[currentSample]) /
118
+ (sampleValues[currentSample + 1] - sampleValues[currentSample]);
119
+ var guessForT = intervalStart + dist * kSampleStepSize;
120
+
121
+ var initialSlope = getSlope(guessForT, mX1, mX2);
122
+ if (initialSlope >= NEWTON_MIN_SLOPE) {
123
+ return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
124
+ } else if (initialSlope === 0.0) {
125
+ return guessForT;
126
+ } else {
127
+ return binarySubdivide(
128
+ aX,
129
+ intervalStart,
130
+ intervalStart + kSampleStepSize,
131
+ mX1,
132
+ mX2
133
+ );
134
+ }
135
+ }
136
+
137
+ return function BezierEasing(x: number) {
138
+ // Because JavaScript number are imprecise, we should guarantee the extremes are right.
139
+ if (x === 0 || x === 1) {
140
+ return x;
141
+ }
142
+ return calcBezier(getTForX(x), mY1, mY2);
143
+ };
144
+ }
145
+
146
+ export { bezier };
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ */
9
+ import { bezier as _bezier } from "./Bezier";
10
+
11
+ /**
12
+ * This class implements common easing functions. The math is pretty obscure,
13
+ * but this cool website has nice visual illustrations of what they represent:
14
+ * http://xaedes.de/dev/transitions/
15
+ */
16
+ export class Easing {
17
+ static step0(n: number) {
18
+ return n > 0 ? 1 : 0;
19
+ }
20
+
21
+ static step1(n: number) {
22
+ return n >= 1 ? 1 : 0;
23
+ }
24
+
25
+ static linear(t: number) {
26
+ return t;
27
+ }
28
+
29
+ static ease(t: number): number {
30
+ return ease(t);
31
+ }
32
+
33
+ static quad(t: number) {
34
+ return t * t;
35
+ }
36
+
37
+ static cubic(t: number) {
38
+ return t * t * t;
39
+ }
40
+
41
+ static poly(n: number) {
42
+ return (t: number) => Math.pow(t, n);
43
+ }
44
+
45
+ static sin(t: number) {
46
+ return 1 - Math.cos((t * Math.PI) / 2);
47
+ }
48
+
49
+ static circle(t: number) {
50
+ return 1 - Math.sqrt(1 - t * t);
51
+ }
52
+
53
+ static exp(t: number) {
54
+ return Math.pow(2, 10 * (t - 1));
55
+ }
56
+
57
+ /**
58
+ * A simple elastic interaction, similar to a spring. Default bounciness
59
+ * is 1, which overshoots a little bit once. 0 bounciness doesn't overshoot
60
+ * at all, and bounciness of N > 1 will overshoot about N times.
61
+ *
62
+ * Wolfram Plots:
63
+ *
64
+ * http://tiny.cc/elastic_b_1 (default bounciness = 1)
65
+ * http://tiny.cc/elastic_b_3 (bounciness = 3)
66
+ */
67
+ static elastic(bounciness: number = 1): (t: number) => number {
68
+ var p = bounciness * Math.PI;
69
+ return (t) =>
70
+ 1 - Math.pow(Math.cos((t * Math.PI) / 2), 3) * Math.cos(t * p);
71
+ }
72
+
73
+ static back(s: number): (t: number) => number {
74
+ if (s === undefined) {
75
+ s = 1.70158;
76
+ }
77
+ return (t) => t * t * ((s + 1) * t - s);
78
+ }
79
+
80
+ static bounce(t: number): number {
81
+ if (t < 1 / 2.75) {
82
+ return 7.5625 * t * t;
83
+ }
84
+
85
+ if (t < 2 / 2.75) {
86
+ t -= 1.5 / 2.75;
87
+ return 7.5625 * t * t + 0.75;
88
+ }
89
+
90
+ if (t < 2.5 / 2.75) {
91
+ t -= 2.25 / 2.75;
92
+ return 7.5625 * t * t + 0.9375;
93
+ }
94
+
95
+ t -= 2.625 / 2.75;
96
+ return 7.5625 * t * t + 0.984375;
97
+ }
98
+
99
+ static bezier(
100
+ x1: number,
101
+ y1: number,
102
+ x2: number,
103
+ y2: number
104
+ ): (t: number) => number {
105
+ return _bezier(x1, y1, x2, y2);
106
+ }
107
+
108
+ static in(easing: (t: number) => number): (t: number) => number {
109
+ return easing;
110
+ }
111
+
112
+ /**
113
+ * Runs an easing function backwards.
114
+ */
115
+ static out(easing: (t: number) => number): (t: number) => number {
116
+ return (t) => 1 - easing(1 - t);
117
+ }
118
+
119
+ /**
120
+ * Makes any easing function symmetrical.
121
+ */
122
+ static inOut(easing: (t: number) => number): (t: number) => number {
123
+ return (t) => {
124
+ if (t < 0.5) {
125
+ return easing(t * 2) / 2;
126
+ }
127
+ return 1 - easing((1 - t) * 2) / 2;
128
+ };
129
+ }
130
+ }
131
+
132
+ var ease = Easing.bezier(0.42, 0, 1, 1);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Converts a camelCase string to kebab-case.
3
+ * e.g. backgroundColor -> background-color
4
+ *
5
+ * @param str - The camelCase string to convert.
6
+ * @returns The converted kebab-case string.
7
+ */
8
+ export function camelCaseToKebabCase(str: string): string {
9
+ return str.replace(/([A-Z])/g, (match) => '-' + match.toLowerCase());
10
+ }
@@ -0,0 +1,16 @@
1
+ import { isFluidValue } from './isFluidValue';
2
+
3
+ /**
4
+ * Filters out properties with fluid values from a given props object.
5
+ * This function removes any properties that are considered fluid values,
6
+ * typically those that subscribe to updates and therefore should not be
7
+ * included in a static props object.
8
+ *
9
+ * @param props - The original props object, which may include fluid values.
10
+ * @returns A new props object with fluid values removed.
11
+ */
12
+ export const getCleanProps = ({ style, ...props }: any) => {
13
+ return Object.fromEntries(
14
+ Object.entries(props).filter(([_, value]) => !isFluidValue(value))
15
+ ) as any;
16
+ };