react-native-smooth-clip-view 0.2.8 → 0.3.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 (132) hide show
  1. package/README.md +86 -21
  2. package/android/CMakeLists.txt +7 -0
  3. package/android/build.gradle +14 -2
  4. package/android/proguard-rules.pro +3 -3
  5. package/android/src/main/cpp/SmoothClipAndroid.h +10 -0
  6. package/android/src/main/cpp/SmoothClipBindings.cpp +896 -6
  7. package/android/src/main/cpp/SmoothClipRegistry.cpp +1067 -46
  8. package/android/src/main/cpp/SmoothClipTrace.h +25 -0
  9. package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +265 -0
  10. package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +21 -0
  11. package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +283 -0
  12. package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +385 -24
  13. package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +138 -24
  14. package/cpp/SmoothClipAnimationCurve.h +151 -122
  15. package/cpp/SmoothClipRegistry.h +102 -4
  16. package/cpp/SmoothClipSharedGeometry.h +146 -7
  17. package/cpp/SmoothClipVelocityTracker.h +13 -9
  18. package/ios/SmoothClipGeometry.h +184 -6
  19. package/ios/SmoothClipRegistry.mm +1033 -25
  20. package/ios/SmoothClipRegistrySnapshot.h +13 -0
  21. package/ios/SmoothClipTurboModule.cpp +857 -2
  22. package/ios/SmoothClipTurboModule.h +310 -0
  23. package/ios/SmoothClipView.mm +714 -183
  24. package/ios/SmoothClipViewRegistry.h +1 -0
  25. package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  26. package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  27. package/lib/module/NativeSmoothClipModule.js.map +1 -1
  28. package/lib/module/SmoothClipView.ios.js +22 -6
  29. package/lib/module/SmoothClipView.ios.js.map +1 -1
  30. package/lib/module/SmoothClipView.js +1 -46
  31. package/lib/module/SmoothClipView.js.map +1 -1
  32. package/lib/module/SmoothClipViewNativeComponent.ts +27 -1
  33. package/lib/module/capabilities.js +4 -0
  34. package/lib/module/capabilities.js.map +1 -0
  35. package/lib/module/capabilities.native.js +36 -0
  36. package/lib/module/capabilities.native.js.map +1 -0
  37. package/lib/module/capabilityTypes.js +11 -0
  38. package/lib/module/capabilityTypes.js.map +1 -0
  39. package/lib/module/driverState.js +0 -28
  40. package/lib/module/driverState.js.map +1 -1
  41. package/lib/module/drivers.js +1 -281
  42. package/lib/module/drivers.js.map +1 -1
  43. package/lib/module/drivers.native.js +340 -75
  44. package/lib/module/drivers.native.js.map +1 -1
  45. package/lib/module/geometry.js +147 -17
  46. package/lib/module/geometry.js.map +1 -1
  47. package/lib/module/groupDriverTypes.js +4 -0
  48. package/lib/module/groupDriverTypes.js.map +1 -0
  49. package/lib/module/groupDrivers.android.js +4 -0
  50. package/lib/module/groupDrivers.android.js.map +1 -0
  51. package/lib/module/groupDrivers.ios.js +4 -0
  52. package/lib/module/groupDrivers.ios.js.map +1 -0
  53. package/lib/module/groupDrivers.js +4 -0
  54. package/lib/module/groupDrivers.js.map +1 -0
  55. package/lib/module/groupDrivers.native.js +799 -0
  56. package/lib/module/groupDrivers.native.js.map +1 -0
  57. package/lib/module/index.js +3 -2
  58. package/lib/module/index.js.map +1 -1
  59. package/lib/module/presentationProtocol.js +15 -0
  60. package/lib/module/presentationProtocol.js.map +1 -0
  61. package/lib/typescript/src/NativeSmoothClipModule.d.ts +25 -0
  62. package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
  63. package/lib/typescript/src/SmoothClipView.d.ts +2 -10
  64. package/lib/typescript/src/SmoothClipView.d.ts.map +1 -1
  65. package/lib/typescript/src/SmoothClipView.ios.d.ts +133 -2
  66. package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -1
  67. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +8 -0
  68. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
  69. package/lib/typescript/src/capabilities.d.ts +3 -0
  70. package/lib/typescript/src/capabilities.d.ts.map +1 -0
  71. package/lib/typescript/src/capabilities.native.d.ts +3 -0
  72. package/lib/typescript/src/capabilities.native.d.ts.map +1 -0
  73. package/lib/typescript/src/capabilityTypes.d.ts +10 -0
  74. package/lib/typescript/src/capabilityTypes.d.ts.map +1 -0
  75. package/lib/typescript/src/driverState.d.ts +1 -6
  76. package/lib/typescript/src/driverState.d.ts.map +1 -1
  77. package/lib/typescript/src/driverTypes.d.ts +39 -11
  78. package/lib/typescript/src/driverTypes.d.ts.map +1 -1
  79. package/lib/typescript/src/drivers.d.ts +2 -4
  80. package/lib/typescript/src/drivers.d.ts.map +1 -1
  81. package/lib/typescript/src/drivers.native.d.ts.map +1 -1
  82. package/lib/typescript/src/geometry.d.ts +36 -2
  83. package/lib/typescript/src/geometry.d.ts.map +1 -1
  84. package/lib/typescript/src/groupDriverTypes.d.ts +66 -0
  85. package/lib/typescript/src/groupDriverTypes.d.ts.map +1 -0
  86. package/lib/typescript/src/groupDrivers.android.d.ts +2 -0
  87. package/lib/typescript/src/groupDrivers.android.d.ts.map +1 -0
  88. package/lib/typescript/src/groupDrivers.d.ts +2 -0
  89. package/lib/typescript/src/groupDrivers.d.ts.map +1 -0
  90. package/lib/typescript/src/groupDrivers.ios.d.ts +2 -0
  91. package/lib/typescript/src/groupDrivers.ios.d.ts.map +1 -0
  92. package/lib/typescript/src/groupDrivers.native.d.ts +4 -0
  93. package/lib/typescript/src/groupDrivers.native.d.ts.map +1 -0
  94. package/lib/typescript/src/index.d.ts +6 -3
  95. package/lib/typescript/src/index.d.ts.map +1 -1
  96. package/lib/typescript/src/presentationProtocol.d.ts +4 -0
  97. package/lib/typescript/src/presentationProtocol.d.ts.map +1 -0
  98. package/package.json +10 -11
  99. package/src/NativeSmoothClipModule.ts +275 -0
  100. package/src/SmoothClipView.ios.tsx +30 -11
  101. package/src/SmoothClipView.tsx +2 -76
  102. package/src/SmoothClipViewNativeComponent.ts +27 -1
  103. package/src/capabilities.native.ts +69 -0
  104. package/src/capabilities.ts +2 -0
  105. package/src/capabilityTypes.ts +17 -0
  106. package/src/driverState.ts +1 -41
  107. package/src/driverTypes.ts +56 -11
  108. package/src/drivers.native.ts +921 -151
  109. package/src/drivers.ts +2 -423
  110. package/src/geometry.ts +231 -27
  111. package/src/groupDriverTypes.ts +117 -0
  112. package/src/groupDrivers.android.ts +1 -0
  113. package/src/groupDrivers.ios.ts +1 -0
  114. package/src/groupDrivers.native.ts +1189 -0
  115. package/src/groupDrivers.ts +1 -0
  116. package/src/index.ts +30 -2
  117. package/src/presentationProtocol.ts +28 -0
  118. package/lib/module/SmoothClipView.web.js +0 -54
  119. package/lib/module/SmoothClipView.web.js.map +0 -1
  120. package/lib/module/index.web.js +0 -8
  121. package/lib/module/index.web.js.map +0 -1
  122. package/lib/module/webClipPath.js +0 -25
  123. package/lib/module/webClipPath.js.map +0 -1
  124. package/lib/typescript/src/SmoothClipView.web.d.ts +0 -10
  125. package/lib/typescript/src/SmoothClipView.web.d.ts.map +0 -1
  126. package/lib/typescript/src/index.web.d.ts +0 -9
  127. package/lib/typescript/src/index.web.d.ts.map +0 -1
  128. package/lib/typescript/src/webClipPath.d.ts +0 -7
  129. package/lib/typescript/src/webClipPath.d.ts.map +0 -1
  130. package/src/SmoothClipView.web.tsx +0 -66
  131. package/src/index.web.ts +0 -23
  132. package/src/webClipPath.ts +0 -30
package/src/geometry.ts CHANGED
@@ -1,9 +1,31 @@
1
+ export type ClipCurve = 'circular' | 'continuous';
2
+
1
3
  export type ClipGeometry = Readonly<{
2
4
  x: number;
3
5
  y: number;
4
6
  width: number;
5
7
  height: number;
8
+ /** Default for every corner without an explicit override. */
6
9
  radius: number;
10
+ topLeftRadius?: number;
11
+ topRightRadius?: number;
12
+ bottomRightRadius?: number;
13
+ bottomLeftRadius?: number;
14
+ curve?: ClipCurve;
15
+ }>;
16
+
17
+ export type CanonicalClipGeometry = Readonly<{
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ /** Normalized legacy all-corners value retained for V1 compatibility. */
23
+ radius: number;
24
+ topLeftRadius: number;
25
+ topRightRadius: number;
26
+ bottomRightRadius: number;
27
+ bottomLeftRadius: number;
28
+ curve: ClipCurve;
7
29
  }>;
8
30
 
9
31
  export type ClipBounds = Readonly<{
@@ -15,15 +37,25 @@ export type SmoothClipPresentation = Readonly<{
15
37
  clip: ClipGeometry;
16
38
  contentTranslateX: number;
17
39
  contentTranslateY: number;
40
+ /** Defaults to 1 when omitted. */
41
+ contentScale?: number;
18
42
  }>;
19
43
 
20
- export function createClipPresentation(
21
- clip: ClipGeometry,
22
- contentTranslateX = 0,
23
- contentTranslateY = 0
24
- ): SmoothClipPresentation {
44
+ export type CanonicalSmoothClipPresentation = Readonly<{
45
+ clip: CanonicalClipGeometry;
46
+ contentTranslateX: number;
47
+ contentTranslateY: number;
48
+ contentScale: number;
49
+ }>;
50
+
51
+ function isClipCurve(curve: ClipCurve | undefined): boolean {
25
52
  'worklet';
26
- return { clip, contentTranslateX, contentTranslateY };
53
+ return curve === undefined || curve === 'circular' || curve === 'continuous';
54
+ }
55
+
56
+ function isFiniteOptionalNumber(value: number | undefined): boolean {
57
+ 'worklet';
58
+ return value === undefined || Number.isFinite(value);
27
59
  }
28
60
 
29
61
  export function isFiniteClipGeometry(geometry: ClipGeometry): boolean {
@@ -33,10 +65,40 @@ export function isFiniteClipGeometry(geometry: ClipGeometry): boolean {
33
65
  Number.isFinite(geometry.y) &&
34
66
  Number.isFinite(geometry.width) &&
35
67
  Number.isFinite(geometry.height) &&
36
- Number.isFinite(geometry.radius)
68
+ Number.isFinite(geometry.radius) &&
69
+ isFiniteOptionalNumber(geometry.topLeftRadius) &&
70
+ isFiniteOptionalNumber(geometry.topRightRadius) &&
71
+ isFiniteOptionalNumber(geometry.bottomRightRadius) &&
72
+ isFiniteOptionalNumber(geometry.bottomLeftRadius) &&
73
+ isClipCurve(geometry.curve)
37
74
  );
38
75
  }
39
76
 
77
+ function resolvedTopLeftRadius(geometry: ClipGeometry): number {
78
+ 'worklet';
79
+ return geometry.topLeftRadius ?? geometry.radius;
80
+ }
81
+
82
+ function resolvedTopRightRadius(geometry: ClipGeometry): number {
83
+ 'worklet';
84
+ return geometry.topRightRadius ?? geometry.radius;
85
+ }
86
+
87
+ function resolvedBottomRightRadius(geometry: ClipGeometry): number {
88
+ 'worklet';
89
+ return geometry.bottomRightRadius ?? geometry.radius;
90
+ }
91
+
92
+ function resolvedBottomLeftRadius(geometry: ClipGeometry): number {
93
+ 'worklet';
94
+ return geometry.bottomLeftRadius ?? geometry.radius;
95
+ }
96
+
97
+ function resolvedCurve(geometry: ClipGeometry): ClipCurve {
98
+ 'worklet';
99
+ return geometry.curve ?? 'circular';
100
+ }
101
+
40
102
  export function clipGeometryEquals(
41
103
  first: ClipGeometry | null,
42
104
  second: ClipGeometry
@@ -48,18 +110,31 @@ export function clipGeometryEquals(
48
110
  first.y === second.y &&
49
111
  first.width === second.width &&
50
112
  first.height === second.height &&
51
- first.radius === second.radius
113
+ first.radius === second.radius &&
114
+ resolvedTopLeftRadius(first) === resolvedTopLeftRadius(second) &&
115
+ resolvedTopRightRadius(first) === resolvedTopRightRadius(second) &&
116
+ resolvedBottomRightRadius(first) === resolvedBottomRightRadius(second) &&
117
+ resolvedBottomLeftRadius(first) === resolvedBottomLeftRadius(second) &&
118
+ resolvedCurve(first) === resolvedCurve(second)
52
119
  );
53
120
  }
54
121
 
122
+ function resolvedContentScale(presentation: SmoothClipPresentation): number {
123
+ 'worklet';
124
+ return presentation.contentScale ?? 1;
125
+ }
126
+
55
127
  export function isFiniteClipPresentation(
56
128
  presentation: SmoothClipPresentation
57
129
  ): boolean {
58
130
  'worklet';
131
+ const contentScale = resolvedContentScale(presentation);
59
132
  return (
60
133
  isFiniteClipGeometry(presentation.clip) &&
61
134
  Number.isFinite(presentation.contentTranslateX) &&
62
- Number.isFinite(presentation.contentTranslateY)
135
+ Number.isFinite(presentation.contentTranslateY) &&
136
+ Number.isFinite(contentScale) &&
137
+ contentScale > 0
63
138
  );
64
139
  }
65
140
 
@@ -72,10 +147,131 @@ export function clipPresentationEquals(
72
147
  first !== null &&
73
148
  clipGeometryEquals(first.clip, second.clip) &&
74
149
  first.contentTranslateX === second.contentTranslateX &&
75
- first.contentTranslateY === second.contentTranslateY
150
+ first.contentTranslateY === second.contentTranslateY &&
151
+ resolvedContentScale(first) === resolvedContentScale(second)
76
152
  );
77
153
  }
78
154
 
155
+ function createCanonicalClipGeometry(
156
+ geometry: ClipGeometry,
157
+ x: number,
158
+ y: number,
159
+ width: number,
160
+ height: number
161
+ ): CanonicalClipGeometry {
162
+ 'worklet';
163
+ const topLeftRadius = Math.max(0, resolvedTopLeftRadius(geometry));
164
+ const topRightRadius = Math.max(0, resolvedTopRightRadius(geometry));
165
+ const bottomRightRadius = Math.max(0, resolvedBottomRightRadius(geometry));
166
+ const bottomLeftRadius = Math.max(0, resolvedBottomLeftRadius(geometry));
167
+
168
+ // CSS corner-overlap reduction uses one common factor so all four corners
169
+ // retain their proportions when either pair exceeds the available edge.
170
+ let scale = 1;
171
+ const top = topLeftRadius + topRightRadius;
172
+ const right = topRightRadius + bottomRightRadius;
173
+ const bottom = bottomLeftRadius + bottomRightRadius;
174
+ const left = topLeftRadius + bottomLeftRadius;
175
+
176
+ if (top > 0) scale = Math.min(scale, width / top);
177
+ if (right > 0) scale = Math.min(scale, height / right);
178
+ if (bottom > 0) scale = Math.min(scale, width / bottom);
179
+ if (left > 0) scale = Math.min(scale, height / left);
180
+ scale = Math.max(0, Math.min(1, scale));
181
+
182
+ const normalizedTopLeftRadius = topLeftRadius * scale;
183
+ const normalizedTopRightRadius = topRightRadius * scale;
184
+ const normalizedBottomRightRadius = bottomRightRadius * scale;
185
+ const normalizedBottomLeftRadius = bottomLeftRadius * scale;
186
+ const radius =
187
+ normalizedTopLeftRadius === normalizedTopRightRadius &&
188
+ normalizedTopRightRadius === normalizedBottomRightRadius &&
189
+ normalizedBottomRightRadius === normalizedBottomLeftRadius
190
+ ? normalizedTopLeftRadius
191
+ : 0;
192
+
193
+ return {
194
+ x,
195
+ y,
196
+ width,
197
+ height,
198
+ radius,
199
+ topLeftRadius: normalizedTopLeftRadius,
200
+ topRightRadius: normalizedTopRightRadius,
201
+ bottomRightRadius: normalizedBottomRightRadius,
202
+ bottomLeftRadius: normalizedBottomLeftRadius,
203
+ curve: resolvedCurve(geometry),
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Expands presentation defaults and applies CSS proportional corner scaling.
209
+ */
210
+ export function canonicalizeClipGeometry(
211
+ geometry: ClipGeometry
212
+ ): CanonicalClipGeometry | null {
213
+ 'worklet';
214
+ if (!isFiniteClipGeometry(geometry)) return null;
215
+
216
+ const width = Math.max(0, geometry.width);
217
+ const height = Math.max(0, geometry.height);
218
+ return createCanonicalClipGeometry(
219
+ geometry,
220
+ geometry.x,
221
+ geometry.y,
222
+ width,
223
+ height
224
+ );
225
+ }
226
+
227
+ export function canonicalizeClipPresentation(
228
+ presentation: SmoothClipPresentation
229
+ ): CanonicalSmoothClipPresentation | null {
230
+ 'worklet';
231
+ if (!isFiniteClipPresentation(presentation)) return null;
232
+
233
+ const clip = canonicalizeClipGeometry(presentation.clip);
234
+ if (clip === null) return null;
235
+
236
+ return {
237
+ clip,
238
+ contentTranslateX: presentation.contentTranslateX,
239
+ contentTranslateY: presentation.contentTranslateY,
240
+ contentScale: resolvedContentScale(presentation),
241
+ };
242
+ }
243
+
244
+ // Keep this below the canonicalization helpers so the worklet never closes
245
+ // over a helper declared later in this module.
246
+ export function createClipPresentation(
247
+ clip: ClipGeometry,
248
+ contentTranslateX = 0,
249
+ contentTranslateY = 0,
250
+ contentScale = 1
251
+ ): CanonicalSmoothClipPresentation {
252
+ 'worklet';
253
+ const canonicalClip = canonicalizeClipGeometry(clip);
254
+ return {
255
+ // Keep invalid input observably invalid so downstream validation remains
256
+ // atomic instead of accidentally sanitizing a required scalar.
257
+ clip: canonicalClip ?? {
258
+ x: clip.x,
259
+ y: clip.y,
260
+ width: clip.width,
261
+ height: clip.height,
262
+ radius: clip.radius,
263
+ topLeftRadius: resolvedTopLeftRadius(clip),
264
+ topRightRadius: resolvedTopRightRadius(clip),
265
+ bottomRightRadius: resolvedBottomRightRadius(clip),
266
+ bottomLeftRadius: resolvedBottomLeftRadius(clip),
267
+ curve: resolvedCurve(clip),
268
+ },
269
+ contentTranslateX,
270
+ contentTranslateY,
271
+ contentScale,
272
+ };
273
+ }
274
+
79
275
  /**
80
276
  * Mirrors the native geometry contract for tests and non-native fallbacks.
81
277
  * Native remains authoritative because its bounds are the actual rendered size.
@@ -83,19 +279,15 @@ export function clipPresentationEquals(
83
279
  export function normalizeClipGeometry(
84
280
  geometry: ClipGeometry,
85
281
  bounds: ClipBounds
86
- ): ClipGeometry | null {
282
+ ): CanonicalClipGeometry | null {
87
283
  'worklet';
88
- const values = [
89
- geometry.x,
90
- geometry.y,
91
- geometry.width,
92
- geometry.height,
93
- geometry.radius,
94
- bounds.width,
95
- bounds.height,
96
- ];
97
-
98
- if (!values.every(Number.isFinite)) return null;
284
+ if (
285
+ !isFiniteClipGeometry(geometry) ||
286
+ !Number.isFinite(bounds.width) ||
287
+ !Number.isFinite(bounds.height)
288
+ ) {
289
+ return null;
290
+ }
99
291
 
100
292
  const boundsWidth = Math.max(0, bounds.width);
101
293
  const boundsHeight = Math.max(0, bounds.height);
@@ -112,11 +304,23 @@ export function normalizeClipGeometry(
112
304
  const width = Math.max(0, right - left);
113
305
  const height = Math.max(0, bottom - top);
114
306
 
307
+ return createCanonicalClipGeometry(geometry, left, top, width, height);
308
+ }
309
+
310
+ export function normalizeClipPresentation(
311
+ presentation: SmoothClipPresentation,
312
+ bounds: ClipBounds
313
+ ): CanonicalSmoothClipPresentation | null {
314
+ 'worklet';
315
+ if (!isFiniteClipPresentation(presentation)) return null;
316
+
317
+ const clip = normalizeClipGeometry(presentation.clip, bounds);
318
+ if (clip === null) return null;
319
+
115
320
  return {
116
- x: left,
117
- y: top,
118
- width,
119
- height,
120
- radius: Math.min(Math.max(0, geometry.radius), Math.min(width, height) / 2),
321
+ clip,
322
+ contentTranslateX: presentation.contentTranslateX,
323
+ contentTranslateY: presentation.contentTranslateY,
324
+ contentScale: resolvedContentScale(presentation),
121
325
  };
122
326
  }
@@ -0,0 +1,117 @@
1
+ import type {
2
+ ClipReduceMotion,
3
+ SmoothClipDriver,
4
+ SpringClipAnimation,
5
+ TimingClipAnimation,
6
+ } from './driverTypes';
7
+ import type {
8
+ CanonicalSmoothClipPresentation,
9
+ SmoothClipPresentation,
10
+ } from './geometry';
11
+
12
+ export type SmoothClipGroupAnimationResult = Readonly<{
13
+ groupId: number;
14
+ finished: boolean;
15
+ }>;
16
+
17
+ export type SmoothClipGroupSnapshot = Readonly<{
18
+ driver: SmoothClipDriver;
19
+ presentation: CanonicalSmoothClipPresentation;
20
+ ready: boolean;
21
+ }>;
22
+
23
+ export type SmoothClipBatchEntry = Readonly<{
24
+ driver: SmoothClipDriver;
25
+ presentation: SmoothClipPresentation;
26
+ }>;
27
+
28
+ export type SmoothClipGroupMotionEntry = Readonly<{
29
+ driver: SmoothClipDriver;
30
+ target: SmoothClipPresentation;
31
+ from?: SmoothClipPresentation;
32
+ }>;
33
+
34
+ export type SmoothClipGroupKeyframeEntry = SmoothClipGroupMotionEntry &
35
+ Readonly<{
36
+ frames: readonly Readonly<{
37
+ offset: number;
38
+ presentation: SmoothClipPresentation;
39
+ }>[];
40
+ }>;
41
+
42
+ export type SmoothClipGroupSuspensionPolicy = 'pause' | 'finish';
43
+ export type SmoothClipGroupCancelBehavior = 'freeze' | 'finish';
44
+
45
+ type SmoothClipGroupAnimationBase = Readonly<{
46
+ suspensionPolicy?: SmoothClipGroupSuspensionPolicy;
47
+ }>;
48
+
49
+ export type SmoothClipGroupTimingAnimation = Omit<TimingClipAnimation, 'from'> &
50
+ SmoothClipGroupAnimationBase;
51
+
52
+ export type SmoothClipGroupSpringAnimation = Omit<SpringClipAnimation, 'from'> &
53
+ SmoothClipGroupAnimationBase;
54
+
55
+ export type SmoothClipGroupKeyframeAnimation = Readonly<{
56
+ type: 'keyframes';
57
+ duration: number;
58
+ suspensionPolicy?: SmoothClipGroupSuspensionPolicy;
59
+ }>;
60
+
61
+ export type SmoothClipGroupMotionAnimation =
62
+ SmoothClipGroupTimingAnimation | SmoothClipGroupSpringAnimation;
63
+
64
+ export type SmoothClipGroupDriverOptions = Readonly<{
65
+ reduceMotion?: ClipReduceMotion;
66
+ onAnimationComplete?: (result: SmoothClipGroupAnimationResult) => void;
67
+ }>;
68
+
69
+ export interface SmoothClipGroupUIControls {
70
+ beginInteraction(
71
+ drivers: readonly SmoothClipDriver[]
72
+ ): readonly SmoothClipGroupSnapshot[];
73
+ snapshotCurrent(
74
+ drivers: readonly SmoothClipDriver[]
75
+ ): readonly SmoothClipGroupSnapshot[];
76
+ setBatch(entries: readonly SmoothClipBatchEntry[]): void;
77
+ animateTo(
78
+ entries: readonly SmoothClipGroupMotionEntry[],
79
+ animation: SmoothClipGroupMotionAnimation
80
+ ): number;
81
+ animateTo(
82
+ entries: readonly SmoothClipGroupKeyframeEntry[],
83
+ animation: SmoothClipGroupKeyframeAnimation
84
+ ): number;
85
+ cancel(
86
+ groupId: number,
87
+ behavior?: SmoothClipGroupCancelBehavior
88
+ ): readonly SmoothClipGroupSnapshot[];
89
+ }
90
+
91
+ export interface SmoothClipGroupReactControls {
92
+ beginInteraction(
93
+ drivers: readonly SmoothClipDriver[]
94
+ ): Promise<readonly SmoothClipGroupSnapshot[]>;
95
+ snapshotCurrent(
96
+ drivers: readonly SmoothClipDriver[]
97
+ ): Promise<readonly SmoothClipGroupSnapshot[]>;
98
+ setBatch(entries: readonly SmoothClipBatchEntry[]): Promise<void>;
99
+ animateTo(
100
+ entries: readonly SmoothClipGroupMotionEntry[],
101
+ animation: SmoothClipGroupMotionAnimation
102
+ ): Promise<number>;
103
+ animateTo(
104
+ entries: readonly SmoothClipGroupKeyframeEntry[],
105
+ animation: SmoothClipGroupKeyframeAnimation
106
+ ): Promise<number>;
107
+ cancel(
108
+ groupId: number,
109
+ behavior?: SmoothClipGroupCancelBehavior
110
+ ): Promise<readonly SmoothClipGroupSnapshot[]>;
111
+ }
112
+
113
+ export type SmoothClipGroupDriver = Readonly<{
114
+ kind: 'group';
115
+ ui: SmoothClipGroupUIControls;
116
+ react: SmoothClipGroupReactControls;
117
+ }>;
@@ -0,0 +1 @@
1
+ export { useSmoothClipGroupDriver } from './groupDrivers.native';
@@ -0,0 +1 @@
1
+ export { useSmoothClipGroupDriver } from './groupDrivers.native';