react-native-smooth-clip-view 0.4.2 → 0.4.3
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.
- package/CHANGELOG.md +44 -0
- package/README.md +74 -0
- package/android/src/main/cpp/SmoothClipAndroid.h +1 -1
- package/android/src/main/cpp/SmoothClipBindings.cpp +14 -8
- package/android/src/main/cpp/SmoothClipRegistry.cpp +6 -6
- package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +23 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +2 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +2 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +124 -32
- package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +16 -0
- package/cpp/SmoothClipAnimationCurve.h +13 -10
- package/cpp/SmoothClipRegistry.h +2 -0
- package/cpp/SmoothClipSharedGeometry.h +20 -0
- package/cpp/SmoothClipVelocityTracker.h +6 -0
- package/ios/SmoothClipTurboModule.cpp +17 -6
- package/ios/SmoothClipTurboModule.h +3 -1
- package/ios/SmoothClipView.mm +241 -22
- package/lib/module/NativeSmoothClipModule.js.map +1 -1
- package/lib/module/SmoothClipView.ios.js +3 -0
- package/lib/module/SmoothClipView.ios.js.map +1 -1
- package/lib/module/SmoothClipViewNativeComponent.ts +5 -1
- package/lib/module/geometry.js +22 -2
- package/lib/module/geometry.js.map +1 -1
- package/lib/module/presentationCodec.js +5 -3
- package/lib/module/presentationCodec.js.map +1 -1
- package/lib/typescript/src/NativeSmoothClipModule.d.ts +1 -1
- package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +3 -1
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/controllerTypes.d.ts +5 -1
- package/lib/typescript/src/controllerTypes.d.ts.map +1 -1
- package/lib/typescript/src/geometry.d.ts +9 -0
- package/lib/typescript/src/geometry.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/presentationCodec.d.ts +1 -1
- package/lib/typescript/src/presentationCodec.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/NativeSmoothClipModule.ts +3 -1
- package/src/SmoothClipView.ios.tsx +3 -0
- package/src/SmoothClipViewNativeComponent.ts +5 -1
- package/src/controllerTypes.ts +5 -1
- package/src/geometry.ts +35 -0
- package/src/index.ts +1 -0
- package/src/presentationCodec.ts +8 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.4.3](https://github.com/kbrattli/react-native-smooth-clip-view/releases/tag/v0.4.3) — 2026-09-11
|
|
4
|
+
|
|
5
|
+
### Rotate and fade the whole clip
|
|
6
|
+
|
|
7
|
+
Animate rotation and opacity alongside clip geometry on iOS and Android. The
|
|
8
|
+
aperture, its content, and its shadow move and fade together inside the fixed
|
|
9
|
+
host, using the existing controller and atomic group APIs.
|
|
10
|
+
|
|
11
|
+
- **Rotation:** pass degree or radian strings such as `'12deg'` or `'0.2rad'`.
|
|
12
|
+
Rotation is clockwise around the current aperture center, after content
|
|
13
|
+
translation and scale. Angles interpolate numerically, so `'720deg'` animates
|
|
14
|
+
two full turns from zero. Interruption snapshots preserve those turns.
|
|
15
|
+
- **Group opacity:** set `opacity` to fade content and shadow together, including
|
|
16
|
+
overlapping children. Finite values clamp to `[0, 1]`; spring rendering clamps
|
|
17
|
+
opacity while preserving the spring's internal motion state.
|
|
18
|
+
- **Animation continuity:** rotation and opacity participate in timing and
|
|
19
|
+
spring animations, cancellation snapshots, and background spring pause/resume.
|
|
20
|
+
Explicit spring velocity applies to these channels too.
|
|
21
|
+
- **Touch and accessibility:** hit testing follows the rotated aperture, including
|
|
22
|
+
clips rotated back into the viewport. Fully transparent content accepts no new
|
|
23
|
+
touches and is hidden from accessibility.
|
|
24
|
+
- **Rendering:** appearance updates use native compositor properties without
|
|
25
|
+
Yoga layout work or rebuilding unchanged clipping paths. Translucent groups
|
|
26
|
+
may require offscreen compositing.
|
|
27
|
+
- **Types and validation:** export `ClipRotation`, include rotation and opacity in
|
|
28
|
+
canonical presentations, and reject malformed angles or nonfinite values
|
|
29
|
+
atomically. Add JavaScript and native regression coverage for these behaviors.
|
|
30
|
+
|
|
31
|
+
### Usage and upgrade notes
|
|
32
|
+
|
|
33
|
+
`rotation` defaults to `'0deg'` and `opacity` to `1`. Presentations are complete:
|
|
34
|
+
omitting either field resets it to its default. Snapshots return rotation in
|
|
35
|
+
radians. See [Rotate and fade a clip](./README.md#rotate-and-fade-a-clip) for a
|
|
36
|
+
controller example.
|
|
37
|
+
|
|
38
|
+
**Rebuild your native app after upgrading**, and run `pod install` on iOS. The
|
|
39
|
+
native presentation protocol has changed; JavaScript from 0.4.3 must run with the
|
|
40
|
+
matching native library, rather than an older binary updated only through OTA.
|
|
41
|
+
|
|
42
|
+
[All changes since 0.4.2](https://github.com/kbrattli/react-native-smooth-clip-view/compare/v0.4.2...v0.4.3)
|
|
43
|
+
|
|
44
|
+
Earlier release notes are available on [GitHub Releases](https://github.com/kbrattli/react-native-smooth-clip-view/releases).
|
package/README.md
CHANGED
|
@@ -134,6 +134,21 @@ defaults match Reanimated 4.5: mass `4`, stiffness `900`, damping `120`, and
|
|
|
134
134
|
relative energy threshold `6e-9`. A spring is rejected when its resolved native
|
|
135
135
|
trajectory could make `contentScale` nonpositive.
|
|
136
136
|
|
|
137
|
+
`velocity` is a shared initial progress velocity in inverse seconds, defaulting
|
|
138
|
+
to `0`. Each changing channel starts with velocity proportional to its remaining
|
|
139
|
+
distance: `velocity * (target - start)`. This includes rotation (in radians) and
|
|
140
|
+
opacity. Public controllers and groups do not automatically inherit gesture
|
|
141
|
+
velocity; starting a new spring after `beginInteraction()` still defaults to `0`
|
|
142
|
+
unless `velocity` is supplied. Pausing and resuming an existing native spring
|
|
143
|
+
preserves its internal motion state; public snapshots return clamped opacity.
|
|
144
|
+
|
|
145
|
+
The internal native standalone path also supports inherited velocity. Its
|
|
146
|
+
projection uses only clip position, size, corner radii, and content translation.
|
|
147
|
+
Rotation, opacity, content scale, and shadow channels do not contribute to that
|
|
148
|
+
projection. The resulting normalized velocity can drive all changing channels,
|
|
149
|
+
including rotation and opacity, without mixing their units into the projection.
|
|
150
|
+
Rotation/opacity-only motion therefore supplies no inherited velocity.
|
|
151
|
+
|
|
137
152
|
An animation requested before the host has a positive layout waits, then starts
|
|
138
153
|
with its full duration. While the application is inactive, native animation
|
|
139
154
|
transactions stay pending and do not report cancellation. Timing animations
|
|
@@ -189,6 +204,15 @@ APIs share validation, run ownership, and completion behavior.
|
|
|
189
204
|
- Corner-overlap scaling follows CSS rules against the requested rectangle.
|
|
190
205
|
- `contentTranslateX`, `contentTranslateY`, and positive `contentScale` animate
|
|
191
206
|
with the aperture.
|
|
207
|
+
- `rotation` accepts degree or radian strings (for example, `'12deg'` or
|
|
208
|
+
`'0.2rad'`) and defaults to `'0deg'`. It rotates the aperture, content, and
|
|
209
|
+
shadow together, clockwise around the current aperture center. Existing
|
|
210
|
+
content translation and scale happen before this rotation. The host stays
|
|
211
|
+
fixed and crops the rotated result.
|
|
212
|
+
- `opacity` defaults to `1` and fades the aperture's content and shadow as one
|
|
213
|
+
group. Finite values clamp to `[0, 1]`; malformed angles and nonfinite values
|
|
214
|
+
reject the complete presentation. Spring opacity is clamped for rendering
|
|
215
|
+
without clamping its internal spring state.
|
|
192
216
|
- Circular and continuous curves and independent corner radii are supported.
|
|
193
217
|
- One outset `boxShadow` is supported. It escapes the aperture but not the host.
|
|
194
218
|
- A fully off-host aperture is not touchable, even when only its shadow overlaps.
|
|
@@ -198,6 +222,52 @@ APIs share validation, run ownership, and completion behavior.
|
|
|
198
222
|
Use `getSmoothClipCapabilities()` when a consumer needs to decide whether a
|
|
199
223
|
complex native path can be promoted on the current platform.
|
|
200
224
|
|
|
225
|
+
### Rotate and fade a clip
|
|
226
|
+
|
|
227
|
+
Rotation and opacity are presentation fields, so they use the same controller
|
|
228
|
+
and group methods as geometry. For example, start a tilted, translucent card
|
|
229
|
+
and animate it upright:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const clip = useSmoothClipController({
|
|
233
|
+
clip: { x: 24, y: 80, width: 240, height: 320, radius: 24 },
|
|
234
|
+
contentTranslateX: 0,
|
|
235
|
+
contentTranslateY: 0,
|
|
236
|
+
rotation: '-12deg',
|
|
237
|
+
opacity: 0.4,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Attach this controller to <SmoothClipView controller={clip}> as above.
|
|
241
|
+
const reveal = () =>
|
|
242
|
+
clip.react.animateTo(
|
|
243
|
+
{
|
|
244
|
+
clip: { x: 24, y: 80, width: 240, height: 320, radius: 24 },
|
|
245
|
+
contentTranslateX: 0,
|
|
246
|
+
contentTranslateY: 0,
|
|
247
|
+
rotation: '0deg',
|
|
248
|
+
opacity: 1,
|
|
249
|
+
},
|
|
250
|
+
{ type: 'spring', stiffness: 180, damping: 22 }
|
|
251
|
+
);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
For gesture-driven updates, supply the same fields from a UI-runtime worklet:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
clip.ui.setFrame({ ...frame, rotation: '12deg', opacity: 0.5 });
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Angles interpolate numerically, so `'720deg'` requests two full turns from zero;
|
|
261
|
+
there is no automatic shortest-path wrapping. Interruption snapshots preserve
|
|
262
|
+
full turns and return rotation as a radian string. Each presentation is complete:
|
|
263
|
+
omitting rotation or opacity resets that field to its default. At zero opacity,
|
|
264
|
+
the content admits no new touches and is hidden from accessibility.
|
|
265
|
+
|
|
266
|
+
When upgrading to **0.4.3**, rebuild the native app (and run `pod install` on
|
|
267
|
+
iOS). The native presentation protocol includes new rotation and opacity
|
|
268
|
+
channels, so a JavaScript-only OTA update cannot upgrade an older native build.
|
|
269
|
+
See the [changelog](./CHANGELOG.md) for release details.
|
|
270
|
+
|
|
201
271
|
## Performance contract
|
|
202
272
|
|
|
203
273
|
- One worklet-to-native call per `ui.setFrame`, or per group batch.
|
|
@@ -205,6 +275,10 @@ complex native path can be promoted on the current platform.
|
|
|
205
275
|
- The shadow-disabled rendering path keeps no shadow drawing resources.
|
|
206
276
|
- The fixed host is the maximum rendering viewport; consumers should size it to
|
|
207
277
|
the region in which content and shadow may appear.
|
|
278
|
+
- Rotation and opacity update native compositor properties without Yoga work
|
|
279
|
+
or rebuilding unchanged clipping paths. Correctly fading overlapping children
|
|
280
|
+
may require offscreen compositing; large translucent groups can cost more GPU
|
|
281
|
+
time than opaque ones. No rasterization or software layer is forced.
|
|
208
282
|
|
|
209
283
|
## License
|
|
210
284
|
|
|
@@ -22,7 +22,7 @@ struct JSmoothClipView : facebook::jni::JavaClass<JSmoothClipView> {
|
|
|
22
22
|
double contentTranslateXPx,
|
|
23
23
|
double contentTranslateYPx,
|
|
24
24
|
double contentScale,
|
|
25
|
-
const Shadow &shadowPx) const;
|
|
25
|
+
const Shadow &shadowPx, double rotation, double opacity) const;
|
|
26
26
|
void setAutonomousMotion(bool active) const;
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -27,7 +27,7 @@ namespace smoothclip {
|
|
|
27
27
|
namespace {
|
|
28
28
|
|
|
29
29
|
constexpr double kMaxSafeJavaScriptInteger = 9007199254740991.0;
|
|
30
|
-
constexpr size_t kPresentationStride =
|
|
30
|
+
constexpr size_t kPresentationStride = 23;
|
|
31
31
|
constexpr size_t kSnapshotStride = kPresentationStride + 1;
|
|
32
32
|
constexpr size_t kMotionEntryStride = kPresentationStride * 2 + 2;
|
|
33
33
|
|
|
@@ -61,7 +61,8 @@ bool finiteBasePresentation(const Presentation &presentation) {
|
|
|
61
61
|
std::isfinite(presentation.contentTranslateX) &&
|
|
62
62
|
std::isfinite(presentation.contentTranslateY) &&
|
|
63
63
|
std::isfinite(presentation.contentScale) &&
|
|
64
|
-
presentation.contentScale > 0
|
|
64
|
+
presentation.contentScale > 0 &&
|
|
65
|
+
std::isfinite(presentation.rotation) && std::isfinite(presentation.opacity);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
bool finitePresentation(const Presentation &presentation) {
|
|
@@ -154,7 +155,7 @@ bool presentationAt(
|
|
|
154
155
|
Shadow{
|
|
155
156
|
packet[12] == 1.0,
|
|
156
157
|
packet[13], packet[14], packet[15], packet[16],
|
|
157
|
-
packet[17], packet[18], packet[19], packet[20]}};
|
|
158
|
+
packet[17], packet[18], packet[19], packet[20]}, packet[21], packet[22]};
|
|
158
159
|
return finitePresentation(result);
|
|
159
160
|
}
|
|
160
161
|
|
|
@@ -190,6 +191,8 @@ void appendPresentation(
|
|
|
190
191
|
result.setValueAtIndex(runtime, offset++, presentation.shadow.offsetY);
|
|
191
192
|
result.setValueAtIndex(runtime, offset++, presentation.shadow.blurRadius);
|
|
192
193
|
result.setValueAtIndex(runtime, offset++, presentation.shadow.spreadDistance);
|
|
194
|
+
result.setValueAtIndex(runtime, offset++, presentation.rotation);
|
|
195
|
+
result.setValueAtIndex(runtime, offset++, presentation.opacity);
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
Array presentationArray(Runtime &runtime, const Presentation &presentation) {
|
|
@@ -551,9 +554,9 @@ void installBindings(
|
|
|
551
554
|
});
|
|
552
555
|
|
|
553
556
|
setHostFunction(
|
|
554
|
-
runtime, bindings, "setClipFrameScalars",
|
|
557
|
+
runtime, bindings, "setClipFrameScalars", 24,
|
|
555
558
|
[](Runtime &, const Value &, const Value *args, size_t count) -> Value {
|
|
556
|
-
if (count <
|
|
559
|
+
if (count < 24) return Value::undefined();
|
|
557
560
|
const double driverId = args[0].asNumber();
|
|
558
561
|
Geometry geometry{
|
|
559
562
|
args[1].asNumber(), args[2].asNumber(), args[3].asNumber(),
|
|
@@ -584,7 +587,7 @@ void installBindings(
|
|
|
584
587
|
args[19].asNumber(),
|
|
585
588
|
args[20].asNumber(),
|
|
586
589
|
args[21].asNumber(),
|
|
587
|
-
}};
|
|
590
|
+
}, args[22].asNumber(), args[23].asNumber()};
|
|
588
591
|
if (validDriverId(driverId) && validCurve(args[9].asNumber()) &&
|
|
589
592
|
finitePresentation(presentation)) {
|
|
590
593
|
setPresentation(
|
|
@@ -828,6 +831,8 @@ void nativeRegisterView(
|
|
|
828
831
|
jdouble shadowOffsetY,
|
|
829
832
|
jdouble shadowBlurRadius,
|
|
830
833
|
jdouble shadowSpreadDistance,
|
|
834
|
+
jdouble rotation,
|
|
835
|
+
jdouble opacity,
|
|
831
836
|
jdouble density,
|
|
832
837
|
jdouble widthPx,
|
|
833
838
|
jdouble heightPx,
|
|
@@ -842,7 +847,8 @@ void nativeRegisterView(
|
|
|
842
847
|
!std::isfinite(shadowBlue) || !std::isfinite(shadowAlpha) ||
|
|
843
848
|
!std::isfinite(shadowOffsetX) ||
|
|
844
849
|
!std::isfinite(shadowOffsetY) || !std::isfinite(shadowBlurRadius) ||
|
|
845
|
-
!std::isfinite(shadowSpreadDistance) ||
|
|
850
|
+
!std::isfinite(shadowSpreadDistance) ||
|
|
851
|
+
!std::isfinite(rotation) || !std::isfinite(opacity) || contentScale <= 0 ||
|
|
846
852
|
shadowRed < 0 || shadowRed > 1 || shadowGreen < 0 || shadowGreen > 1 ||
|
|
847
853
|
shadowBlue < 0 || shadowBlue > 1 || shadowAlpha < 0 || shadowAlpha > 1 ||
|
|
848
854
|
shadowBlurRadius < 0 ||
|
|
@@ -874,7 +880,7 @@ void nativeRegisterView(
|
|
|
874
880
|
static_cast<uint64_t>(driverId),
|
|
875
881
|
view,
|
|
876
882
|
smoothclip::Presentation{
|
|
877
|
-
geometry, contentTranslateX, contentTranslateY, contentScale, shadow},
|
|
883
|
+
geometry, contentTranslateX, contentTranslateY, contentScale, shadow, rotation, opacity},
|
|
878
884
|
density,
|
|
879
885
|
widthPx,
|
|
880
886
|
heightPx,
|
|
@@ -458,7 +458,7 @@ void deliverToView(const ViewEntry &entry, const Presentation &presentation) {
|
|
|
458
458
|
translateX,
|
|
459
459
|
translateY,
|
|
460
460
|
presentation.contentScale,
|
|
461
|
-
shadowPx);
|
|
461
|
+
shadowPx, presentation.rotation, presentation.opacity);
|
|
462
462
|
}
|
|
463
463
|
|
|
464
464
|
void applyToViews(DriverState &state, const Presentation &presentation) {
|
|
@@ -1705,7 +1705,7 @@ void JSmoothClipView::applyClip(const Presentation &presentation) const {
|
|
|
1705
1705
|
jdouble,
|
|
1706
1706
|
jdouble,
|
|
1707
1707
|
jdouble,
|
|
1708
|
-
jdouble)>("setClipPresentationDip");
|
|
1708
|
+
jdouble, jdouble, jdouble)>("setClipPresentationDip");
|
|
1709
1709
|
method(
|
|
1710
1710
|
self(),
|
|
1711
1711
|
presentation.clip.x,
|
|
@@ -1732,7 +1732,7 @@ void JSmoothClipView::applyClip(const Presentation &presentation) const {
|
|
|
1732
1732
|
presentation.shadow.offsetX,
|
|
1733
1733
|
presentation.shadow.offsetY,
|
|
1734
1734
|
presentation.shadow.blurRadius,
|
|
1735
|
-
presentation.shadow.spreadDistance);
|
|
1735
|
+
presentation.shadow.spreadDistance, presentation.rotation, presentation.opacity);
|
|
1736
1736
|
}
|
|
1737
1737
|
|
|
1738
1738
|
void JSmoothClipView::applyClipPx(
|
|
@@ -1740,7 +1740,7 @@ void JSmoothClipView::applyClipPx(
|
|
|
1740
1740
|
double contentTranslateXPx,
|
|
1741
1741
|
double contentTranslateYPx,
|
|
1742
1742
|
double contentScale,
|
|
1743
|
-
const Shadow &shadowPx) const {
|
|
1743
|
+
const Shadow &shadowPx, double rotation, double opacity) const {
|
|
1744
1744
|
static const auto method =
|
|
1745
1745
|
javaClassStatic()
|
|
1746
1746
|
->getMethod<void(
|
|
@@ -1764,7 +1764,7 @@ void JSmoothClipView::applyClipPx(
|
|
|
1764
1764
|
jfloat,
|
|
1765
1765
|
jfloat,
|
|
1766
1766
|
jfloat,
|
|
1767
|
-
jfloat)>("setClipPresentationPx");
|
|
1767
|
+
jfloat, jdouble, jfloat)>("setClipPresentationPx");
|
|
1768
1768
|
method(
|
|
1769
1769
|
self(),
|
|
1770
1770
|
static_cast<jfloat>(clip.left),
|
|
@@ -1787,7 +1787,7 @@ void JSmoothClipView::applyClipPx(
|
|
|
1787
1787
|
static_cast<jfloat>(shadowPx.offsetX),
|
|
1788
1788
|
static_cast<jfloat>(shadowPx.offsetY),
|
|
1789
1789
|
static_cast<jfloat>(shadowPx.blurRadius),
|
|
1790
|
-
static_cast<jfloat>(shadowPx.spreadDistance));
|
|
1790
|
+
static_cast<jfloat>(shadowPx.spreadDistance), rotation, static_cast<jfloat>(opacity));
|
|
1791
1791
|
}
|
|
1792
1792
|
|
|
1793
1793
|
void JSmoothClipView::setAutonomousMotion(bool active) const {
|
|
@@ -240,3 +240,26 @@ internal fun clipAccessibility(
|
|
|
240
240
|
} else {
|
|
241
241
|
requestedAccessibility
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
/** Conservative for rounded corners, exact for the rotated bounding rectangle. */
|
|
245
|
+
internal fun rotatedRectIntersectsHost(
|
|
246
|
+
left: Double, top: Double, right: Double, bottom: Double,
|
|
247
|
+
pivotX: Double, pivotY: Double, rotation: Double, hostWidth: Double, hostHeight: Double,
|
|
248
|
+
): Boolean {
|
|
249
|
+
if (right <= left || bottom <= top || hostWidth <= 0 || hostHeight <= 0) return false
|
|
250
|
+
if (rotation == 0.0) return right > 0 && bottom > 0 && left < hostWidth && top < hostHeight
|
|
251
|
+
val c = kotlin.math.cos(rotation)
|
|
252
|
+
val s = kotlin.math.sin(rotation)
|
|
253
|
+
val dx = (left + right) / 2 - pivotX
|
|
254
|
+
val dy = (top + bottom) / 2 - pivotY
|
|
255
|
+
val x = pivotX + c * dx - s * dy - hostWidth / 2
|
|
256
|
+
val y = pivotY + s * dx + c * dy - hostHeight / 2
|
|
257
|
+
val hw = (right - left) / 2
|
|
258
|
+
val hh = (bottom - top) / 2
|
|
259
|
+
val ac = kotlin.math.abs(c)
|
|
260
|
+
val ass = kotlin.math.abs(s)
|
|
261
|
+
return kotlin.math.abs(x) < hostWidth / 2 + ac * hw + ass * hh &&
|
|
262
|
+
kotlin.math.abs(y) < hostHeight / 2 + ass * hw + ac * hh &&
|
|
263
|
+
kotlin.math.abs(c * x + s * y) < hw + ac * hostWidth / 2 + ass * hostHeight / 2 &&
|
|
264
|
+
kotlin.math.abs(-s * x + c * y) < hh + ass * hostWidth / 2 + ac * hostHeight / 2
|
|
265
|
+
}
|
|
@@ -140,6 +140,8 @@ class SmoothClipModule(context: ReactApplicationContext) :
|
|
|
140
140
|
shadowOffsetY: Double,
|
|
141
141
|
shadowBlurRadius: Double,
|
|
142
142
|
shadowSpreadDistance: Double,
|
|
143
|
+
rotation: Double,
|
|
144
|
+
opacity: Double,
|
|
143
145
|
) = Unit
|
|
144
146
|
|
|
145
147
|
override fun beginInteraction(driverId: Double): WritableArray =
|