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/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/react-native-smooth-clip-view.svg)](https://www.npmjs.com/package/react-native-smooth-clip-view)
4
4
 
5
+ https://github.com/user-attachments/assets/899235b3-de69-46d7-b6db-61bc54d80df8
6
+
7
+ <sub>Card zoom and shared-element gallery transitions, captured at 60fps — [direct clip](https://github.com/kbrattli/react-native-smooth-clip-view/blob/main/docs/media/smooth-clip-demo.mp4).</sub>
8
+
5
9
  ## High-performance geometry animations for React Native
6
10
 
7
11
  `react-native-smooth-clip-view` lets you animate `x`, `y`, `width`, `height`, and `borderRadius` with Reanimated without triggering expensive layout work on every frame.
@@ -16,10 +20,11 @@ Use it for transitions that previously struggled with performance when animating
16
20
  - React Native Reanimated 4.5 or newer
17
21
  - React Native Worklets 0.10 or newer
18
22
  - iOS 16.4 or newer
19
- - Android API 26 or newer
23
+ - Android API 33 or newer
20
24
 
21
- The package supports iOS, Android, and React Native Web. It does not include a
22
- legacy Paper implementation.
25
+ The package supports iOS and Android. React Native Web and the legacy Paper
26
+ architecture are not supported; keep imports and rendered usage behind native
27
+ platform boundaries.
23
28
 
24
29
  ## Installation
25
30
 
@@ -97,8 +102,9 @@ const styles = StyleSheet.create({
97
102
  ```
98
103
 
99
104
  The same driver can be passed to multiple hosts. One native registry update
100
- fans the seven-scalar presentation out to all mounted hosts. Interactive
101
- updates avoid Yoga and ShadowTree commits.
105
+ fans the presentation out to all mounted hosts. The original seven-scalar V1
106
+ protocol remains unchanged; V2 adds per-corner radii, continuous curves, and
107
+ centered content scale. Interactive updates avoid Yoga and ShadowTree commits.
102
108
 
103
109
  For transitions whose endpoint is known, let Core Animation interpolate on the
104
110
  render server:
@@ -126,6 +132,20 @@ vsync clock with registry fanout; outline calculation and invalidation still
126
132
  run on its UI thread. Springs are physically integrated per geometry channel
127
133
  and finish when they settle below sub-pixel thresholds on both platforms.
128
134
  Retargeting starts from visible state.
135
+
136
+ Blocked-thread behavior: a blocked JS thread never stalls a running
137
+ transition on either platform — no JS runs on the frame path. A blocked
138
+ main thread stalls it on Android (the frame loop and the View property
139
+ writes are main-thread-only by platform design; the RenderThread only
140
+ replays what the main thread records) but not on iOS, where the render
141
+ server advances installed Core Animations out of process. The Android
142
+ behavior is not recoverable through public APIs — RenderThread-driven
143
+ property animation (`RenderNodeAnimator`, what ripples use) is hidden API —
144
+ and it is also the coherent choice for this library: parallel Reanimated
145
+ content runs on the main thread on both platforms, so on Android the clip
146
+ and its content stall and resume together, while on iOS a main-thread stall
147
+ lets the natively animated channels keep moving past any Reanimated-driven
148
+ ones.
129
149
  The same driver can be grabbed by a gesture without a visual jump:
130
150
 
131
151
  ```tsx
@@ -146,6 +166,9 @@ const gesture = Gesture.Pan()
146
166
  // geometry as `from` so the animation starts from exactly that value —
147
167
  // it fuses a setScalars hot write with the handoff in one call.
148
168
  const clip = geometryForDrag(dragStart.value, event.translationY);
169
+ // 'inherit' projects launch speed from the drag's last two samples. On
170
+ // Android that sampling is opt-in — create the driver with
171
+ // useSmoothClipDriver(initial, { velocityTracking: true }).
149
172
  driver.ui.animateTo(createClipPresentation(expandedClip), {
150
173
  type: 'spring',
151
174
  initialVelocity: 'inherit',
@@ -194,13 +217,27 @@ puts on screen, which is the property worth keeping identical.
194
217
  as `animation.from` — `animateTo` then performs the hot write and the
195
218
  handoff in one call. Do not interleave `setScalars` with
196
219
  `presentation.value` writes on the same driver.
220
+ - `driver.ui.setPresentationScalars(x, y, width, height, topLeft, topRight,
221
+ bottomRight, bottomLeft, curveCode, tx, ty, scale)` is the V2 hot path.
222
+ `curveCode` is `0` for circular and `1` for continuous. V2 values are
223
+ validated as one transaction; widened values are never silently downgraded
224
+ onto a V1 native binary.
197
225
  - Spring `initialVelocity` is one normalized scalar along the current-to-target
198
226
  trajectory, in units of the remaining distance per second (`1` covers the
199
227
  remaining distance in one second). Every geometry channel continues with the
200
228
  same normalized rate, so grab/release preserves the felt direction and
201
229
  speed. `'inherit'` (the default) estimates the scalar from the last two
202
- interactive samples on iOS and Android; the web fallback always inherits
203
- zero. How long the finger has been still since that last sample scales the
230
+ interactive samples on iOS and Android. On Android, sampling on the
231
+ `setScalars` hot path is **opt-in**: pass
232
+ `velocityTracking: true` to `useSmoothClipDriver` or `'inherit'` inherits
233
+ zero after a hot-write drag (a dev-mode warning flags this). **Behavior
234
+ change:** earlier releases always recorded on Android, so an existing
235
+ `setScalars`-drag → inherit-spring handoff keeps its momentum only after
236
+ adding the flag. The recording
237
+ is a clock read plus channel copies on every per-frame write, so drivers
238
+ that never hand off into an inherit spring skip it by default. iOS always
239
+ records, and Android's declarative `presentation.value` channel always
240
+ records too. How long the finger has been still since that last sample scales the
204
241
  result: full credit for one frame (16.7 ms), then a linear decay to zero at
205
242
  100 ms. A release straight out of a drag is therefore untouched, and holding
206
243
  still before releasing bleeds the momentum off smoothly instead of keeping
@@ -235,10 +272,9 @@ puts on screen, which is the property worth keeping identical.
235
272
  starts the replacement from that native value. Passive hook seeds and public
236
273
  `set`/`setScalars` writes still leave a held latch intact. `from` behaves the
237
274
  same on both platforms (it is driver-layer, not native): on iOS the seed
238
- stops any running Core Animation and writes the model layer first; keyframes
239
- then start exactly at `from`, while timing/spring sample their from-value off
240
- the presentation layer — the last committed frame, at most one frame behind
241
- `from` — identical to the explicit two-call pattern.
275
+ stops any running Core Animation, applies `from` to the model layer, and
276
+ installs timing, spring, or keyframe playback from that exact presentation in
277
+ the same start transaction.
242
278
  - `cancel()` freezes visible presentation by default. Pass `'target'` as its
243
279
  behavior to jump to the requested endpoint.
244
280
  - `options.onAnimationComplete` fires exactly once per animation with its ID
@@ -300,6 +336,30 @@ bounds, so a clip that extended beyond the host comes back clamped. Start
300
336
  gestures with `beginInteraction()`: interactive writes issued while native
301
337
  still owns rendering are dropped.
302
338
 
339
+ ### Group driver
340
+
341
+ `useSmoothClipGroupDriver({ reduceMotion, onAnimationComplete })` coordinates
342
+ multiple drivers with one native group ID and one completion. Its worklet-safe
343
+ `ui` and Promise-based `react` interfaces expose:
344
+
345
+ - `beginInteraction(drivers)` to freeze every overlapping group atomically and
346
+ return canonical visible snapshots in input order.
347
+ - `snapshotCurrent(drivers)` to sample presentation and readiness without
348
+ changing ownership.
349
+ - `setBatch(entries)` to validate every entry before committing one native
350
+ transaction.
351
+ - `animateTo(entries, animation)` for shared timing, spring, or linear
352
+ keyframe progress. Membership is immutable for that group ID; a replacement
353
+ is a new atomically installed group.
354
+ - `cancel(groupId, 'freeze' | 'finish')` to return every participant snapshot.
355
+
356
+ Groups wait until all participants have a visible, attached, laid-out,
357
+ positive-size host. The default `suspensionPolicy: 'pause'` freezes and
358
+ re-latches the whole group if any participant loses readiness; `'finish'`
359
+ applies every target. Complex-path native settlement is capability-gated—use
360
+ `getSmoothClipCapabilities()` and keep streaming with `setBatch` when
361
+ `autonomousComplexPathAnimation` is false.
362
+
303
363
  ### `SmoothClipPresentation`
304
364
 
305
365
  ```ts
@@ -307,6 +367,7 @@ type SmoothClipPresentation = Readonly<{
307
367
  clip: ClipGeometry;
308
368
  contentTranslateX: number;
309
369
  contentTranslateY: number;
370
+ contentScale?: number;
310
371
  }>;
311
372
  ```
312
373
 
@@ -323,12 +384,19 @@ type ClipGeometry = Readonly<{
323
384
  width: number;
324
385
  height: number;
325
386
  radius: number;
387
+ topLeftRadius?: number;
388
+ topRightRadius?: number;
389
+ bottomRightRadius?: number;
390
+ bottomLeftRadius?: number;
391
+ curve?: 'circular' | 'continuous';
326
392
  }>;
327
393
  ```
328
394
 
329
395
  Values use React Native points/DIPs. Native code rejects non-finite updates,
330
396
  intersects the requested rectangle with the actual host bounds, prevents
331
- negative sizes, and clamps `radius` to half of the visible shortest edge.
397
+ negative sizes, and proportionally scales overlapping corners with the CSS
398
+ corner-normalization rule. Content scale is centered on the native content
399
+ container; translation is independent and is not multiplied by scale.
332
400
 
333
401
  ### `normalizeClipGeometry`
334
402
 
@@ -350,23 +418,21 @@ pass it as the `driver` prop, and move per-frame updates from the
350
418
  - Give the host its fixed maximum `width` and `height`; clipping never changes
351
419
  Yoga layout.
352
420
  - Put visual backgrounds inside `SmoothClipView`.
353
- - Borders, shadows, host corner styles, host `overflow`, per-corner radii, and
354
- externally applied anisotropic transforms are unsupported.
355
- - Version 0.1.0 supports one uniform corner radius.
356
- - On web, the implementation uses CSS `clip-path` on the fixed host, so
357
- descendant percentages and right/bottom anchoring still resolve against the
358
- maximum footprint.
421
+ - Keep borders, shadows, rotation, and anisotropic transforms on an outer
422
+ visual carrier rather than the clip host.
423
+ - Uniform circular corners use platform fast paths. Unequal or continuous
424
+ corners use a fixed-topology portable path; Android intentionally does not
425
+ claim pixel identity with Apple's proprietary continuous curve.
359
426
 
360
427
  ## Example and development
361
428
 
362
429
  The [`example`](./example) workspace is an Expo SDK 57 app that exercises the
363
- package through its public import on iOS, Android, and web.
430
+ package through its public import on iOS and Android.
364
431
 
365
432
  ```sh
366
433
  npm install
367
434
  npm run example -- ios
368
435
  npm run example -- android
369
- npm run example -- web
370
436
  ```
371
437
 
372
438
  Run the repository checks with:
@@ -376,7 +442,6 @@ npm run lint
376
442
  npm run typecheck
377
443
  npm test
378
444
  npm run prepare
379
- npm run example -- build:web
380
445
  ```
381
446
 
382
447
  ## License
@@ -40,3 +40,10 @@ target_link_libraries(
40
40
  fbjni::fbjni
41
41
  ReactAndroid::jsi
42
42
  ReactAndroid::reactnative)
43
+
44
+ # Debug-only hot-path ATrace slices; see SmoothClipTrace.h.
45
+ # Passed from the debug build type in build.gradle, never for release.
46
+ if(SMOOTH_CLIP_ENABLE_ATRACE)
47
+ target_compile_definitions(smoothclipview PRIVATE SMOOTH_CLIP_ENABLE_ATRACE=1)
48
+ target_link_libraries(smoothclipview android)
49
+ endif()
@@ -1,7 +1,7 @@
1
1
  buildscript {
2
2
  ext.SmoothClipView = [
3
3
  kotlinVersion: "2.0.21",
4
- minSdkVersion: 26,
4
+ minSdkVersion: 33,
5
5
  compileSdkVersion: 36,
6
6
  targetSdkVersion: 36
7
7
  ]
@@ -76,7 +76,11 @@ android {
76
76
  }
77
77
 
78
78
  defaultConfig {
79
- minSdkVersion getExtOrDefault("minSdkVersion")
79
+ // Outline.setPath only guarantees arbitrary path clipping from API 33.
80
+ // Keep this as a hard library floor: allowing a consuming root project to
81
+ // override it lower would make the V2 per-corner/continuous path silently
82
+ // unsupported at runtime.
83
+ minSdkVersion SmoothClipView.minSdkVersion
80
84
  targetSdkVersion getExtOrDefault("targetSdkVersion")
81
85
  // C++ resolves SmoothClipView by name and calls setClipPresentationDip via
82
86
  // a cached jmethodID; consumer minification must not rename or strip them.
@@ -100,6 +104,14 @@ android {
100
104
  }
101
105
 
102
106
  buildTypes {
107
+ debug {
108
+ externalNativeBuild {
109
+ cmake {
110
+ // Hot-path ATrace slices; see SmoothClipTrace.h.
111
+ arguments "-DSMOOTH_CLIP_ENABLE_ATRACE=ON"
112
+ }
113
+ }
114
+ }
103
115
  release {
104
116
  minifyEnabled false
105
117
  }
@@ -1,6 +1,6 @@
1
1
  # SmoothClipView is resolved from C++ by name (fbjni findClassStatic) and its
2
- # setClipPresentationDip / setClipPresentationPx are invoked through cached
3
- # jmethodIDs; SmoothClipBindings registers native methods by name. None of them
4
- # may be renamed or stripped in consumer release builds.
2
+ # V1/V2 setClipPresentation*Dip / setClipPresentation*Px are invoked through
3
+ # cached jmethodIDs; SmoothClipBindings registers native methods by name. None
4
+ # of them may be renamed or stripped in consumer release builds.
5
5
  -keep class com.smoothclipview.SmoothClipView { *; }
6
6
  -keep class com.smoothclipview.SmoothClipBindings { *; }
@@ -18,10 +18,16 @@ struct JSmoothClipView : facebook::jni::JavaClass<JSmoothClipView> {
18
18
  static constexpr auto kJavaDescriptor = "Lcom/smoothclipview/SmoothClipView;";
19
19
 
20
20
  void applyClip(const Presentation &presentation) const;
21
+ void applyClipV2(const Presentation &presentation) const;
21
22
  void applyClipPx(
22
23
  const NormalizedClip &clip,
23
24
  double contentTranslateXPx,
24
25
  double contentTranslateYPx) const;
26
+ void applyClipV2Px(
27
+ const NormalizedClip &clip,
28
+ double contentTranslateXPx,
29
+ double contentTranslateYPx,
30
+ double contentScale) const;
25
31
  };
26
32
 
27
33
  // Called from Kotlin (SmoothClipViewManager) on the UI thread when a Fabric
@@ -57,6 +63,10 @@ void setViewLifecycleVisibilityAndroid(
57
63
  // seconds; never lets a failure unwind back into doFrame.
58
64
  void onFrameAndroid(double frameTimeS);
59
65
 
66
+ // Non-destructive V2 snapshot for the public snapshotCurrentV2 binding.
67
+ // beginInteraction remains the explicit ownership-taking/cancelling operation.
68
+ Presentation snapshotCurrentAndroid(uint64_t driverId);
69
+
60
70
  // Installs `global.__SmoothClipView` (worklet-callable host functions) into the
61
71
  // JS runtime and wires native animation completion delivery through the
62
72
  // CallInvoker. Invoked by the TurboModule BindingsInstaller.