react-native-smooth-clip-view 0.1.0 → 0.2.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 (113) hide show
  1. package/README.md +164 -43
  2. package/SmoothClipView.podspec +8 -2
  3. package/android/CMakeLists.txt +39 -0
  4. package/android/build.gradle +69 -2
  5. package/android/proguard-rules.pro +6 -0
  6. package/android/src/main/cpp/SmoothClipAndroid.h +59 -0
  7. package/android/src/main/cpp/SmoothClipBindings.cpp +428 -0
  8. package/android/src/main/cpp/SmoothClipRegistry.cpp +913 -0
  9. package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +25 -0
  10. package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +55 -0
  11. package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +128 -0
  12. package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +164 -30
  13. package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +107 -10
  14. package/android/src/main/java/com/smoothclipview/SmoothClipViewPackage.kt +18 -2
  15. package/cpp/SmoothClipRegistry.h +93 -0
  16. package/cpp/SmoothClipSharedGeometry.h +50 -0
  17. package/ios/SmoothClipModuleProvider.h +9 -0
  18. package/ios/SmoothClipModuleProvider.mm +16 -0
  19. package/ios/SmoothClipRegistry.mm +717 -0
  20. package/ios/SmoothClipTurboModule.cpp +290 -0
  21. package/ios/SmoothClipTurboModule.h +132 -0
  22. package/ios/SmoothClipView.mm +976 -85
  23. package/ios/SmoothClipViewRegistry.h +27 -0
  24. package/lib/module/NativeSmoothClipModule.js +5 -0
  25. package/lib/module/NativeSmoothClipModule.js.map +1 -0
  26. package/lib/module/SmoothClipView.android.js +4 -0
  27. package/lib/module/SmoothClipView.android.js.map +1 -0
  28. package/lib/module/SmoothClipView.ios.js +34 -0
  29. package/lib/module/SmoothClipView.ios.js.map +1 -0
  30. package/lib/module/SmoothClipView.js +26 -12
  31. package/lib/module/SmoothClipView.js.map +1 -1
  32. package/lib/module/SmoothClipView.web.js +28 -12
  33. package/lib/module/SmoothClipView.web.js.map +1 -1
  34. package/lib/module/SmoothClipViewNativeComponent.ts +14 -1
  35. package/lib/module/driverState.js +102 -0
  36. package/lib/module/driverState.js.map +1 -0
  37. package/lib/module/driverTypes.js +4 -0
  38. package/lib/module/driverTypes.js.map +1 -0
  39. package/lib/module/drivers.android.js +4 -0
  40. package/lib/module/drivers.android.js.map +1 -0
  41. package/lib/module/drivers.ios.js +380 -0
  42. package/lib/module/drivers.ios.js.map +1 -0
  43. package/lib/module/drivers.js +276 -0
  44. package/lib/module/drivers.js.map +1 -0
  45. package/lib/module/geometry.js +19 -0
  46. package/lib/module/geometry.js.map +1 -1
  47. package/lib/module/index.js +2 -0
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/index.web.js +2 -0
  50. package/lib/module/index.web.js.map +1 -1
  51. package/lib/module/nativeCompletion.js +21 -0
  52. package/lib/module/nativeCompletion.js.map +1 -0
  53. package/lib/module/reactRequests.js +50 -0
  54. package/lib/module/reactRequests.js.map +1 -0
  55. package/lib/module/smoothClipNative.android.js +15 -0
  56. package/lib/module/smoothClipNative.android.js.map +1 -0
  57. package/lib/module/smoothClipNative.js +8 -0
  58. package/lib/module/smoothClipNative.js.map +1 -0
  59. package/lib/typescript/src/NativeSmoothClipModule.d.ts +19 -0
  60. package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -0
  61. package/lib/typescript/src/SmoothClipView.android.d.ts +3 -0
  62. package/lib/typescript/src/SmoothClipView.android.d.ts.map +1 -0
  63. package/lib/typescript/src/SmoothClipView.d.ts +5 -6
  64. package/lib/typescript/src/SmoothClipView.d.ts.map +1 -1
  65. package/lib/typescript/src/SmoothClipView.ios.d.ts +9 -0
  66. package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -0
  67. package/lib/typescript/src/SmoothClipView.web.d.ts +5 -7
  68. package/lib/typescript/src/SmoothClipView.web.d.ts.map +1 -1
  69. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +4 -0
  70. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
  71. package/lib/typescript/src/driverState.d.ts +31 -0
  72. package/lib/typescript/src/driverState.d.ts.map +1 -0
  73. package/lib/typescript/src/driverTypes.d.ts +61 -0
  74. package/lib/typescript/src/driverTypes.d.ts.map +1 -0
  75. package/lib/typescript/src/drivers.android.d.ts +3 -0
  76. package/lib/typescript/src/drivers.android.d.ts.map +1 -0
  77. package/lib/typescript/src/drivers.d.ts +5 -0
  78. package/lib/typescript/src/drivers.d.ts.map +1 -0
  79. package/lib/typescript/src/drivers.ios.d.ts +5 -0
  80. package/lib/typescript/src/drivers.ios.d.ts.map +1 -0
  81. package/lib/typescript/src/geometry.d.ts +8 -0
  82. package/lib/typescript/src/geometry.d.ts.map +1 -1
  83. package/lib/typescript/src/index.d.ts +4 -1
  84. package/lib/typescript/src/index.d.ts.map +1 -1
  85. package/lib/typescript/src/index.web.d.ts +4 -1
  86. package/lib/typescript/src/index.web.d.ts.map +1 -1
  87. package/lib/typescript/src/nativeCompletion.d.ts +7 -0
  88. package/lib/typescript/src/nativeCompletion.d.ts.map +1 -0
  89. package/lib/typescript/src/reactRequests.d.ts +7 -0
  90. package/lib/typescript/src/reactRequests.d.ts.map +1 -0
  91. package/lib/typescript/src/smoothClipNative.android.d.ts +4 -0
  92. package/lib/typescript/src/smoothClipNative.android.d.ts.map +1 -0
  93. package/lib/typescript/src/smoothClipNative.d.ts +3 -0
  94. package/lib/typescript/src/smoothClipNative.d.ts.map +1 -0
  95. package/package.json +12 -7
  96. package/src/NativeSmoothClipModule.ts +104 -0
  97. package/src/SmoothClipView.android.tsx +2 -0
  98. package/src/SmoothClipView.ios.tsx +36 -0
  99. package/src/SmoothClipView.tsx +31 -27
  100. package/src/SmoothClipView.web.tsx +26 -22
  101. package/src/SmoothClipViewNativeComponent.ts +14 -1
  102. package/src/driverState.ts +150 -0
  103. package/src/driverTypes.ts +91 -0
  104. package/src/drivers.android.ts +6 -0
  105. package/src/drivers.ios.ts +665 -0
  106. package/src/drivers.ts +416 -0
  107. package/src/geometry.ts +39 -0
  108. package/src/index.ts +19 -1
  109. package/src/index.web.ts +19 -1
  110. package/src/nativeCompletion.ts +37 -0
  111. package/src/reactRequests.ts +64 -0
  112. package/src/smoothClipNative.android.ts +20 -0
  113. package/src/smoothClipNative.ts +5 -0
@@ -0,0 +1,290 @@
1
+ #include "SmoothClipTurboModule.h"
2
+
3
+ #include "SmoothClipRegistry.h"
4
+
5
+ #include <cmath>
6
+ #include <utility>
7
+
8
+ namespace facebook::react {
9
+ namespace {
10
+
11
+ constexpr double kMaxSafeJavaScriptInteger = 9007199254740991.0;
12
+
13
+ bool validDriverId(double value) {
14
+ return std::isfinite(value) && value > 0 &&
15
+ value <= kMaxSafeJavaScriptInteger && std::floor(value) == value;
16
+ }
17
+
18
+ bool finiteGeometry(const smoothclip::Geometry &geometry) {
19
+ return std::isfinite(geometry.x) && std::isfinite(geometry.y) &&
20
+ std::isfinite(geometry.width) && std::isfinite(geometry.height) &&
21
+ std::isfinite(geometry.radius);
22
+ }
23
+
24
+ bool finitePresentation(const smoothclip::Presentation &presentation) {
25
+ return finiteGeometry(presentation.clip) &&
26
+ std::isfinite(presentation.contentTranslateX) &&
27
+ std::isfinite(presentation.contentTranslateY);
28
+ }
29
+
30
+ jsi::Array presentationArray(
31
+ jsi::Runtime &runtime,
32
+ smoothclip::Presentation presentation,
33
+ bool includeHandled = false,
34
+ bool handled = true) {
35
+ const size_t offset = includeHandled ? 1 : 0;
36
+ jsi::Array result(runtime, offset + 7);
37
+ // JS checks `values[0] !== 1`, so the handled flag must be a number: a jsi
38
+ // bool would make every comparison fail and leave the driver stuck in
39
+ // native ownership after cancelAnimation.
40
+ if (includeHandled) result.setValueAtIndex(runtime, 0, handled ? 1.0 : 0.0);
41
+ result.setValueAtIndex(runtime, offset, presentation.clip.x);
42
+ result.setValueAtIndex(runtime, offset + 1, presentation.clip.y);
43
+ result.setValueAtIndex(runtime, offset + 2, presentation.clip.width);
44
+ result.setValueAtIndex(runtime, offset + 3, presentation.clip.height);
45
+ result.setValueAtIndex(runtime, offset + 4, presentation.clip.radius);
46
+ result.setValueAtIndex(runtime, offset + 5, presentation.contentTranslateX);
47
+ result.setValueAtIndex(runtime, offset + 6, presentation.contentTranslateY);
48
+ return result;
49
+ }
50
+
51
+ } // namespace
52
+
53
+ SmoothClipTurboModule::SmoothClipTurboModule(
54
+ std::shared_ptr<CallInvoker> jsInvoker)
55
+ : NativeSmoothClipModuleCxxSpec(std::move(jsInvoker)) {
56
+ smoothclip::setCompletionCallback(
57
+ this,
58
+ [this](uint64_t driverId, int32_t animationId, bool finished) {
59
+ emitOnClipAnimationComplete(SmoothClipAnimationCompletion{
60
+ static_cast<double>(driverId), animationId, finished});
61
+ });
62
+ }
63
+
64
+ SmoothClipTurboModule::~SmoothClipTurboModule() {
65
+ smoothclip::clearCompletionCallback(this);
66
+ }
67
+
68
+ void SmoothClipTurboModule::setClipPresentation(
69
+ jsi::Runtime &,
70
+ double driverId,
71
+ double x,
72
+ double y,
73
+ double width,
74
+ double height,
75
+ double radius,
76
+ double contentTranslateX,
77
+ double contentTranslateY,
78
+ bool takeOwnership) {
79
+ const smoothclip::Presentation presentation{
80
+ {x, y, width, height, radius}, contentTranslateX, contentTranslateY};
81
+ if (validDriverId(driverId) && finitePresentation(presentation)) {
82
+ smoothclip::setPresentation(
83
+ static_cast<uint64_t>(driverId), presentation, takeOwnership);
84
+ }
85
+ }
86
+
87
+ jsi::Array SmoothClipTurboModule::beginInteraction(
88
+ jsi::Runtime &runtime,
89
+ double driverId) {
90
+ if (!validDriverId(driverId)) {
91
+ return presentationArray(runtime, {{0, 0, 0, 0, 0}, 0, 0});
92
+ }
93
+ return presentationArray(
94
+ runtime,
95
+ smoothclip::beginInteraction(static_cast<uint64_t>(driverId)));
96
+ }
97
+
98
+ int32_t SmoothClipTurboModule::animateTiming(
99
+ jsi::Runtime &,
100
+ double driverId,
101
+ bool hasInteractiveStart,
102
+ double startX,
103
+ double startY,
104
+ double startWidth,
105
+ double startHeight,
106
+ double startRadius,
107
+ double startContentTranslateX,
108
+ double startContentTranslateY,
109
+ double x,
110
+ double y,
111
+ double width,
112
+ double height,
113
+ double radius,
114
+ double contentTranslateX,
115
+ double contentTranslateY,
116
+ double durationMs,
117
+ double controlPoint1X,
118
+ double controlPoint1Y,
119
+ double controlPoint2X,
120
+ double controlPoint2Y,
121
+ int32_t reduceMotion) {
122
+ const smoothclip::Presentation startPresentation{
123
+ {startX, startY, startWidth, startHeight, startRadius},
124
+ startContentTranslateX,
125
+ startContentTranslateY};
126
+ const smoothclip::Presentation presentation{
127
+ {x, y, width, height, radius}, contentTranslateX, contentTranslateY};
128
+ const smoothclip::TimingAnimation animation{
129
+ durationMs,
130
+ controlPoint1X,
131
+ controlPoint1Y,
132
+ controlPoint2X,
133
+ controlPoint2Y,
134
+ reduceMotion};
135
+ if (!validDriverId(driverId) ||
136
+ !finitePresentation(startPresentation) ||
137
+ !finitePresentation(presentation) ||
138
+ !std::isfinite(durationMs) || !std::isfinite(controlPoint1X) ||
139
+ !std::isfinite(controlPoint1Y) || !std::isfinite(controlPoint2X) ||
140
+ !std::isfinite(controlPoint2Y)) return 0;
141
+
142
+ return smoothclip::animateTiming(
143
+ static_cast<uint64_t>(driverId),
144
+ {hasInteractiveStart, startPresentation},
145
+ presentation,
146
+ animation);
147
+ }
148
+
149
+ int32_t SmoothClipTurboModule::animateSpring(
150
+ jsi::Runtime &,
151
+ double driverId,
152
+ bool hasInteractiveStart,
153
+ double startX,
154
+ double startY,
155
+ double startWidth,
156
+ double startHeight,
157
+ double startRadius,
158
+ double startContentTranslateX,
159
+ double startContentTranslateY,
160
+ double x,
161
+ double y,
162
+ double width,
163
+ double height,
164
+ double radius,
165
+ double contentTranslateX,
166
+ double contentTranslateY,
167
+ double mass,
168
+ double stiffness,
169
+ double damping,
170
+ double initialVelocity,
171
+ bool inheritVelocity,
172
+ int32_t reduceMotion) {
173
+ const smoothclip::Presentation startPresentation{
174
+ {startX, startY, startWidth, startHeight, startRadius},
175
+ startContentTranslateX,
176
+ startContentTranslateY};
177
+ const smoothclip::Presentation presentation{
178
+ {x, y, width, height, radius}, contentTranslateX, contentTranslateY};
179
+ const smoothclip::SpringAnimation animation{
180
+ mass,
181
+ stiffness,
182
+ damping,
183
+ initialVelocity,
184
+ inheritVelocity,
185
+ reduceMotion};
186
+ if (!validDriverId(driverId) ||
187
+ !finitePresentation(startPresentation) ||
188
+ !finitePresentation(presentation) ||
189
+ !std::isfinite(mass) || !std::isfinite(stiffness) ||
190
+ !std::isfinite(damping) || !std::isfinite(initialVelocity) ||
191
+ mass <= 0 || stiffness <= 0 || damping < 0) return 0;
192
+
193
+ return smoothclip::animateSpring(
194
+ static_cast<uint64_t>(driverId),
195
+ {hasInteractiveStart, startPresentation},
196
+ presentation,
197
+ animation);
198
+ }
199
+
200
+ int32_t SmoothClipTurboModule::animateKeyframes(
201
+ jsi::Runtime &runtime,
202
+ double driverId,
203
+ bool hasInteractiveStart,
204
+ double startX,
205
+ double startY,
206
+ double startWidth,
207
+ double startHeight,
208
+ double startRadius,
209
+ double startContentTranslateX,
210
+ double startContentTranslateY,
211
+ double x,
212
+ double y,
213
+ double width,
214
+ double height,
215
+ double radius,
216
+ double contentTranslateX,
217
+ double contentTranslateY,
218
+ double durationMs,
219
+ jsi::Array frames,
220
+ int32_t reduceMotion) {
221
+ const smoothclip::Presentation startPresentation{
222
+ {startX, startY, startWidth, startHeight, startRadius},
223
+ startContentTranslateX,
224
+ startContentTranslateY};
225
+ const smoothclip::Presentation presentation{
226
+ {x, y, width, height, radius}, contentTranslateX, contentTranslateY};
227
+ if (!validDriverId(driverId) ||
228
+ !finitePresentation(startPresentation) ||
229
+ !finitePresentation(presentation) || !std::isfinite(durationMs) ||
230
+ frames.size(runtime) < 16 || frames.size(runtime) % 8 != 0) {
231
+ return 0;
232
+ }
233
+
234
+ std::vector<smoothclip::Keyframe> keyframes;
235
+ keyframes.reserve(frames.size(runtime) / 8);
236
+ double previousOffset = -1;
237
+ for (size_t index = 0; index < frames.size(runtime); index += 8) {
238
+ const double offset = frames.getValueAtIndex(runtime, index).asNumber();
239
+ smoothclip::Presentation frame{
240
+ {frames.getValueAtIndex(runtime, index + 1).asNumber(),
241
+ frames.getValueAtIndex(runtime, index + 2).asNumber(),
242
+ frames.getValueAtIndex(runtime, index + 3).asNumber(),
243
+ frames.getValueAtIndex(runtime, index + 4).asNumber(),
244
+ frames.getValueAtIndex(runtime, index + 5).asNumber()},
245
+ frames.getValueAtIndex(runtime, index + 6).asNumber(),
246
+ frames.getValueAtIndex(runtime, index + 7).asNumber()};
247
+ if (!std::isfinite(offset) || offset < 0 || offset > 1 ||
248
+ offset <= previousOffset || !finitePresentation(frame)) return 0;
249
+ previousOffset = offset;
250
+ keyframes.push_back({offset, frame});
251
+ }
252
+ if (keyframes.front().offset != 0 || keyframes.back().offset != 1) return 0;
253
+ return smoothclip::animateKeyframes(
254
+ static_cast<uint64_t>(driverId),
255
+ {hasInteractiveStart, startPresentation},
256
+ presentation,
257
+ durationMs,
258
+ std::move(keyframes),
259
+ reduceMotion);
260
+ }
261
+
262
+ int32_t SmoothClipTurboModule::rejectAnimation(
263
+ jsi::Runtime &,
264
+ double driverId) {
265
+ if (!validDriverId(driverId)) return 0;
266
+ return smoothclip::rejectAnimation(static_cast<uint64_t>(driverId));
267
+ }
268
+
269
+ jsi::Array SmoothClipTurboModule::cancelAnimation(
270
+ jsi::Runtime &runtime,
271
+ double driverId,
272
+ int32_t animationId,
273
+ int32_t behavior) {
274
+ if (!validDriverId(driverId)) {
275
+ return presentationArray(
276
+ runtime, {{0, 0, 0, 0, 0}, 0, 0}, true, false);
277
+ }
278
+ const smoothclip::CancelResult result = smoothclip::cancelAnimation(
279
+ static_cast<uint64_t>(driverId), animationId, behavior == 1);
280
+ return presentationArray(
281
+ runtime, result.presentation, true, result.handled);
282
+ }
283
+
284
+ void SmoothClipTurboModule::destroyDriver(jsi::Runtime &, double driverId) {
285
+ if (validDriverId(driverId)) {
286
+ smoothclip::destroyDriver(static_cast<uint64_t>(driverId));
287
+ }
288
+ }
289
+
290
+ } // namespace facebook::react
@@ -0,0 +1,132 @@
1
+ #pragma once
2
+
3
+ #include <SmoothClipViewSpecJSI.h>
4
+
5
+ namespace facebook::react {
6
+
7
+ struct SmoothClipAnimationCompletion {
8
+ double driverId;
9
+ int32_t animationId;
10
+ bool finished;
11
+ };
12
+
13
+ template <>
14
+ struct Bridging<SmoothClipAnimationCompletion> {
15
+ static SmoothClipAnimationCompletion fromJs(
16
+ jsi::Runtime &runtime,
17
+ const jsi::Object &value) {
18
+ return {
19
+ value.getProperty(runtime, "driverId").asNumber(),
20
+ static_cast<int32_t>(
21
+ value.getProperty(runtime, "animationId").asNumber()),
22
+ value.getProperty(runtime, "finished").getBool()};
23
+ }
24
+
25
+ static jsi::Object toJs(
26
+ jsi::Runtime &runtime,
27
+ const SmoothClipAnimationCompletion &value) {
28
+ jsi::Object result(runtime);
29
+ result.setProperty(runtime, "driverId", value.driverId);
30
+ result.setProperty(runtime, "animationId", value.animationId);
31
+ result.setProperty(runtime, "finished", value.finished);
32
+ return result;
33
+ }
34
+ };
35
+
36
+ class SmoothClipTurboModule final
37
+ : public NativeSmoothClipModuleCxxSpec<SmoothClipTurboModule> {
38
+ public:
39
+ explicit SmoothClipTurboModule(std::shared_ptr<CallInvoker> jsInvoker);
40
+ ~SmoothClipTurboModule() override;
41
+
42
+ void setClipPresentation(
43
+ jsi::Runtime &runtime,
44
+ double driverId,
45
+ double x,
46
+ double y,
47
+ double width,
48
+ double height,
49
+ double radius,
50
+ double contentTranslateX,
51
+ double contentTranslateY,
52
+ bool takeOwnership);
53
+ jsi::Array beginInteraction(jsi::Runtime &runtime, double driverId);
54
+ int32_t animateTiming(
55
+ jsi::Runtime &runtime,
56
+ double driverId,
57
+ bool hasInteractiveStart,
58
+ double startX,
59
+ double startY,
60
+ double startWidth,
61
+ double startHeight,
62
+ double startRadius,
63
+ double startContentTranslateX,
64
+ double startContentTranslateY,
65
+ double x,
66
+ double y,
67
+ double width,
68
+ double height,
69
+ double radius,
70
+ double contentTranslateX,
71
+ double contentTranslateY,
72
+ double durationMs,
73
+ double controlPoint1X,
74
+ double controlPoint1Y,
75
+ double controlPoint2X,
76
+ double controlPoint2Y,
77
+ int32_t reduceMotion);
78
+ int32_t animateSpring(
79
+ jsi::Runtime &runtime,
80
+ double driverId,
81
+ bool hasInteractiveStart,
82
+ double startX,
83
+ double startY,
84
+ double startWidth,
85
+ double startHeight,
86
+ double startRadius,
87
+ double startContentTranslateX,
88
+ double startContentTranslateY,
89
+ double x,
90
+ double y,
91
+ double width,
92
+ double height,
93
+ double radius,
94
+ double contentTranslateX,
95
+ double contentTranslateY,
96
+ double mass,
97
+ double stiffness,
98
+ double damping,
99
+ double initialVelocity,
100
+ bool inheritVelocity,
101
+ int32_t reduceMotion);
102
+ int32_t animateKeyframes(
103
+ jsi::Runtime &runtime,
104
+ double driverId,
105
+ bool hasInteractiveStart,
106
+ double startX,
107
+ double startY,
108
+ double startWidth,
109
+ double startHeight,
110
+ double startRadius,
111
+ double startContentTranslateX,
112
+ double startContentTranslateY,
113
+ double x,
114
+ double y,
115
+ double width,
116
+ double height,
117
+ double radius,
118
+ double contentTranslateX,
119
+ double contentTranslateY,
120
+ double durationMs,
121
+ jsi::Array frames,
122
+ int32_t reduceMotion);
123
+ int32_t rejectAnimation(jsi::Runtime &runtime, double driverId);
124
+ jsi::Array cancelAnimation(
125
+ jsi::Runtime &runtime,
126
+ double driverId,
127
+ int32_t animationId,
128
+ int32_t behavior);
129
+ void destroyDriver(jsi::Runtime &runtime, double driverId);
130
+ };
131
+
132
+ } // namespace facebook::react