react-native-smooth-clip-view 0.2.9 → 0.4.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.
- package/README.md +132 -349
- package/android/build.gradle +8 -4
- package/android/proguard-rules.pro +3 -3
- package/android/src/main/cpp/SmoothClipAndroid.h +13 -6
- package/android/src/main/cpp/SmoothClipBindings.cpp +605 -123
- package/android/src/main/cpp/SmoothClipRegistry.cpp +975 -209
- package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +192 -118
- package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +22 -4
- package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +81 -56
- package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +449 -240
- package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +150 -38
- package/cpp/SmoothClipAnimationCurve.h +317 -397
- package/cpp/SmoothClipRegistry.h +84 -20
- package/cpp/SmoothClipSharedGeometry.h +131 -22
- package/cpp/SmoothClipVelocityTracker.h +16 -12
- package/ios/SmoothClipGeometry.h +188 -21
- package/ios/SmoothClipRegistry.mm +869 -368
- package/ios/SmoothClipRegistrySnapshot.h +13 -0
- package/ios/SmoothClipTurboModule.cpp +513 -156
- package/ios/SmoothClipTurboModule.h +123 -56
- package/ios/SmoothClipView.mm +1074 -449
- package/ios/SmoothClipViewRegistry.h +3 -7
- package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/lib/module/NativeSmoothClipModule.js.map +1 -1
- package/lib/module/SmoothClipView.ios.js +94 -11
- package/lib/module/SmoothClipView.ios.js.map +1 -1
- package/lib/module/SmoothClipView.js +1 -46
- package/lib/module/SmoothClipView.js.map +1 -1
- package/lib/module/SmoothClipViewNativeComponent.ts +32 -12
- package/lib/module/capabilities.js +4 -0
- package/lib/module/capabilities.js.map +1 -0
- package/lib/module/capabilities.native.js +18 -0
- package/lib/module/capabilities.native.js.map +1 -0
- package/lib/module/capabilityTypes.js +2 -0
- package/lib/module/capabilityTypes.js.map +1 -0
- package/lib/module/controllerInternals.js +28 -0
- package/lib/module/controllerInternals.js.map +1 -0
- package/lib/module/controllerLifecycle.js +9 -0
- package/lib/module/controllerLifecycle.js.map +1 -0
- package/lib/module/controllerTypes.js +4 -0
- package/lib/module/controllerTypes.js.map +1 -0
- package/lib/module/controllers.android.js +4 -0
- package/lib/module/controllers.android.js.map +1 -0
- package/lib/module/controllers.ios.js +4 -0
- package/lib/module/controllers.ios.js.map +1 -0
- package/lib/module/controllers.js +4 -0
- package/lib/module/controllers.js.map +1 -0
- package/lib/module/controllers.native.js +89 -0
- package/lib/module/controllers.native.js.map +1 -0
- package/lib/module/geometry.js +180 -30
- package/lib/module/geometry.js.map +1 -1
- package/lib/module/groupTypes.js +4 -0
- package/lib/module/groupTypes.js.map +1 -0
- package/lib/module/groups.android.js +4 -0
- package/lib/module/groups.android.js.map +1 -0
- package/lib/module/groups.ios.js +4 -0
- package/lib/module/groups.ios.js.map +1 -0
- package/lib/module/groups.js +4 -0
- package/lib/module/groups.js.map +1 -0
- package/lib/module/groups.native.js +399 -0
- package/lib/module/groups.native.js.map +1 -0
- package/lib/module/ids.js +8 -0
- package/lib/module/ids.js.map +1 -0
- package/lib/module/index.js +4 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/nativeCompletion.js +37 -16
- package/lib/module/nativeCompletion.js.map +1 -1
- package/lib/module/presentationCodec.js +81 -0
- package/lib/module/presentationCodec.js.map +1 -0
- package/lib/typescript/src/NativeSmoothClipModule.d.ts +20 -4
- package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipView.d.ts +2 -10
- package/lib/typescript/src/SmoothClipView.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipView.ios.d.ts +139 -4
- package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +16 -3
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/capabilities.d.ts +3 -0
- package/lib/typescript/src/capabilities.d.ts.map +1 -0
- package/lib/typescript/src/capabilities.native.d.ts +3 -0
- package/lib/typescript/src/capabilities.native.d.ts.map +1 -0
- package/lib/typescript/src/capabilityTypes.d.ts +4 -0
- package/lib/typescript/src/capabilityTypes.d.ts.map +1 -0
- package/lib/typescript/src/controllerInternals.d.ts +14 -0
- package/lib/typescript/src/controllerInternals.d.ts.map +1 -0
- package/lib/typescript/src/controllerLifecycle.d.ts +3 -0
- package/lib/typescript/src/controllerLifecycle.d.ts.map +1 -0
- package/lib/typescript/src/controllerTypes.d.ts +62 -0
- package/lib/typescript/src/controllerTypes.d.ts.map +1 -0
- package/lib/typescript/src/controllers.android.d.ts +2 -0
- package/lib/typescript/src/controllers.android.d.ts.map +1 -0
- package/lib/typescript/src/controllers.d.ts +2 -0
- package/lib/typescript/src/controllers.d.ts.map +1 -0
- package/lib/typescript/src/controllers.ios.d.ts +2 -0
- package/lib/typescript/src/controllers.ios.d.ts.map +1 -0
- package/lib/typescript/src/controllers.native.d.ts +3 -0
- package/lib/typescript/src/controllers.native.d.ts.map +1 -0
- package/lib/typescript/src/geometry.d.ts +49 -5
- package/lib/typescript/src/geometry.d.ts.map +1 -1
- package/lib/typescript/src/groupTypes.d.ts +31 -0
- package/lib/typescript/src/groupTypes.d.ts.map +1 -0
- package/lib/typescript/src/groups.android.d.ts +2 -0
- package/lib/typescript/src/groups.android.d.ts.map +1 -0
- package/lib/typescript/src/groups.d.ts +2 -0
- package/lib/typescript/src/groups.d.ts.map +1 -0
- package/lib/typescript/src/groups.ios.d.ts +2 -0
- package/lib/typescript/src/groups.ios.d.ts.map +1 -0
- package/lib/typescript/src/groups.native.d.ts +3 -0
- package/lib/typescript/src/groups.native.d.ts.map +1 -0
- package/lib/typescript/src/ids.d.ts +2 -0
- package/lib/typescript/src/ids.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +8 -5
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nativeCompletion.d.ts +16 -6
- package/lib/typescript/src/nativeCompletion.d.ts.map +1 -1
- package/lib/typescript/src/presentationCodec.d.ts +10 -0
- package/lib/typescript/src/presentationCodec.d.ts.map +1 -0
- package/package.json +17 -13
- package/src/NativeSmoothClipModule.ts +80 -56
- package/src/SmoothClipView.ios.tsx +142 -16
- package/src/SmoothClipView.tsx +6 -76
- package/src/SmoothClipViewNativeComponent.ts +32 -12
- package/src/capabilities.native.ts +19 -0
- package/src/capabilities.ts +2 -0
- package/src/capabilityTypes.ts +3 -0
- package/src/controllerInternals.ts +52 -0
- package/src/controllerLifecycle.ts +6 -0
- package/src/controllerTypes.ts +87 -0
- package/src/controllers.android.ts +1 -0
- package/src/controllers.ios.ts +1 -0
- package/src/controllers.native.ts +104 -0
- package/src/controllers.ts +1 -0
- package/src/geometry.ts +293 -45
- package/src/groupTypes.ts +53 -0
- package/src/groups.android.ts +1 -0
- package/src/groups.ios.ts +1 -0
- package/src/groups.native.ts +604 -0
- package/src/groups.ts +1 -0
- package/src/ids.ts +6 -0
- package/src/index.ts +32 -12
- package/src/nativeCompletion.ts +67 -32
- package/src/presentationCodec.ts +134 -0
- package/lib/module/SmoothClipView.web.js +0 -54
- package/lib/module/SmoothClipView.web.js.map +0 -1
- package/lib/module/driverState.js +0 -110
- package/lib/module/driverState.js.map +0 -1
- package/lib/module/driverTypes.js +0 -4
- package/lib/module/driverTypes.js.map +0 -1
- package/lib/module/drivers.android.js +0 -6
- package/lib/module/drivers.android.js.map +0 -1
- package/lib/module/drivers.ios.js +0 -6
- package/lib/module/drivers.ios.js.map +0 -1
- package/lib/module/drivers.js +0 -284
- package/lib/module/drivers.js.map +0 -1
- package/lib/module/drivers.native.js +0 -556
- package/lib/module/drivers.native.js.map +0 -1
- package/lib/module/index.web.js +0 -8
- package/lib/module/index.web.js.map +0 -1
- package/lib/module/reactRequests.js +0 -56
- package/lib/module/reactRequests.js.map +0 -1
- package/lib/module/webClipPath.js +0 -25
- package/lib/module/webClipPath.js.map +0 -1
- package/lib/typescript/src/SmoothClipView.web.d.ts +0 -10
- package/lib/typescript/src/SmoothClipView.web.d.ts.map +0 -1
- package/lib/typescript/src/driverState.d.ts +0 -31
- package/lib/typescript/src/driverState.d.ts.map +0 -1
- package/lib/typescript/src/driverTypes.d.ts +0 -107
- package/lib/typescript/src/driverTypes.d.ts.map +0 -1
- package/lib/typescript/src/drivers.android.d.ts +0 -3
- package/lib/typescript/src/drivers.android.d.ts.map +0 -1
- package/lib/typescript/src/drivers.d.ts +0 -5
- package/lib/typescript/src/drivers.d.ts.map +0 -1
- package/lib/typescript/src/drivers.ios.d.ts +0 -3
- package/lib/typescript/src/drivers.ios.d.ts.map +0 -1
- package/lib/typescript/src/drivers.native.d.ts +0 -5
- package/lib/typescript/src/drivers.native.d.ts.map +0 -1
- package/lib/typescript/src/index.web.d.ts +0 -9
- package/lib/typescript/src/index.web.d.ts.map +0 -1
- package/lib/typescript/src/reactRequests.d.ts +0 -9
- package/lib/typescript/src/reactRequests.d.ts.map +0 -1
- package/lib/typescript/src/webClipPath.d.ts +0 -7
- package/lib/typescript/src/webClipPath.d.ts.map +0 -1
- package/src/SmoothClipView.web.tsx +0 -66
- package/src/driverState.ts +0 -158
- package/src/driverTypes.ts +0 -140
- package/src/drivers.android.ts +0 -8
- package/src/drivers.ios.ts +0 -8
- package/src/drivers.native.ts +0 -899
- package/src/drivers.ts +0 -427
- package/src/index.web.ts +0 -23
- package/src/reactRequests.ts +0 -76
- package/src/webClipPath.ts +0 -30
package/src/SmoothClipView.tsx
CHANGED
|
@@ -1,76 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
useAnimatedRef,
|
|
8
|
-
} from 'react-native-reanimated';
|
|
9
|
-
import type { SmoothClipDriver } from './driverTypes';
|
|
10
|
-
import { getDriverState, registerDriverView } from './driverState';
|
|
11
|
-
import { clipPresentationEquals, isFiniteClipPresentation } from './geometry';
|
|
12
|
-
import NativeSmoothClipView, {
|
|
13
|
-
type NativeProps,
|
|
14
|
-
} from './SmoothClipViewNativeComponent';
|
|
15
|
-
|
|
16
|
-
const AnimatedNativeSmoothClipView =
|
|
17
|
-
Animated.createAnimatedComponent(NativeSmoothClipView);
|
|
18
|
-
|
|
19
|
-
export type SmoothClipViewProps = ViewProps & {
|
|
20
|
-
driver: SmoothClipDriver;
|
|
21
|
-
children?: ReactNode;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/** Android fallback. iOS resolves SmoothClipView.ios.tsx instead. */
|
|
25
|
-
export function SmoothClipView({
|
|
26
|
-
driver,
|
|
27
|
-
children,
|
|
28
|
-
...viewProps
|
|
29
|
-
}: SmoothClipViewProps) {
|
|
30
|
-
const { driverId, initialPresentation, source } = getDriverState(driver);
|
|
31
|
-
const { clip } = initialPresentation;
|
|
32
|
-
useEffect(() => registerDriverView(driver), [driver]);
|
|
33
|
-
const nativeRef =
|
|
34
|
-
useAnimatedRef<React.ComponentRef<typeof NativeSmoothClipView>>();
|
|
35
|
-
|
|
36
|
-
useAnimatedReaction(
|
|
37
|
-
() => source.value,
|
|
38
|
-
(presentation, previousPresentation) => {
|
|
39
|
-
if (
|
|
40
|
-
!isFiniteClipPresentation(presentation) ||
|
|
41
|
-
clipPresentationEquals(previousPresentation, presentation)
|
|
42
|
-
) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
dispatchCommand(nativeRef, 'setClipPresentation', [
|
|
47
|
-
presentation.clip.x,
|
|
48
|
-
presentation.clip.y,
|
|
49
|
-
presentation.clip.width,
|
|
50
|
-
presentation.clip.height,
|
|
51
|
-
presentation.clip.radius,
|
|
52
|
-
presentation.contentTranslateX,
|
|
53
|
-
presentation.contentTranslateY,
|
|
54
|
-
]);
|
|
55
|
-
},
|
|
56
|
-
[nativeRef, source]
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
const nativeProps: NativeProps = {
|
|
60
|
-
...viewProps,
|
|
61
|
-
driverId,
|
|
62
|
-
initialClipX: clip.x,
|
|
63
|
-
initialClipY: clip.y,
|
|
64
|
-
initialClipWidth: clip.width,
|
|
65
|
-
initialClipHeight: clip.height,
|
|
66
|
-
initialClipRadius: clip.radius,
|
|
67
|
-
initialContentTranslateX: initialPresentation.contentTranslateX,
|
|
68
|
-
initialContentTranslateY: initialPresentation.contentTranslateY,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<AnimatedNativeSmoothClipView ref={nativeRef} {...nativeProps}>
|
|
73
|
-
{children}
|
|
74
|
-
</AnimatedNativeSmoothClipView>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
1
|
+
export {
|
|
2
|
+
renderSmoothClipView,
|
|
3
|
+
sanitizeSmoothClipStyle,
|
|
4
|
+
SmoothClipView,
|
|
5
|
+
} from './SmoothClipView.ios';
|
|
6
|
+
export type { SmoothClipViewProps } from './SmoothClipView.ios';
|
|
@@ -12,34 +12,54 @@ export interface NativeProps extends ViewProps {
|
|
|
12
12
|
initialClipY: CodegenTypes.Double;
|
|
13
13
|
initialClipWidth: CodegenTypes.Double;
|
|
14
14
|
initialClipHeight: CodegenTypes.Double;
|
|
15
|
-
|
|
15
|
+
initialClipTopLeftRadius: CodegenTypes.Double;
|
|
16
|
+
initialClipTopRightRadius: CodegenTypes.Double;
|
|
17
|
+
initialClipBottomRightRadius: CodegenTypes.Double;
|
|
18
|
+
initialClipBottomLeftRadius: CodegenTypes.Double;
|
|
19
|
+
initialClipCurve: CodegenTypes.Int32;
|
|
16
20
|
initialContentTranslateX: CodegenTypes.Double;
|
|
17
21
|
initialContentTranslateY: CodegenTypes.Double;
|
|
22
|
+
initialContentScale: CodegenTypes.Double;
|
|
23
|
+
initialClipBoxShadowEnabled: boolean;
|
|
24
|
+
initialClipBoxShadowRed: CodegenTypes.Double;
|
|
25
|
+
initialClipBoxShadowGreen: CodegenTypes.Double;
|
|
26
|
+
initialClipBoxShadowBlue: CodegenTypes.Double;
|
|
27
|
+
initialClipBoxShadowAlpha: CodegenTypes.Double;
|
|
28
|
+
initialClipBoxShadowOffsetX: CodegenTypes.Double;
|
|
29
|
+
initialClipBoxShadowOffsetY: CodegenTypes.Double;
|
|
30
|
+
initialClipBoxShadowBlurRadius: CodegenTypes.Double;
|
|
31
|
+
initialClipBoxShadowSpreadDistance: CodegenTypes.Double;
|
|
18
32
|
}
|
|
19
33
|
|
|
20
34
|
interface NativeCommands {
|
|
21
|
-
setClipGeometry: (
|
|
22
|
-
viewRef: React.ElementRef<HostComponent<NativeProps>>,
|
|
23
|
-
x: CodegenTypes.Double,
|
|
24
|
-
y: CodegenTypes.Double,
|
|
25
|
-
width: CodegenTypes.Double,
|
|
26
|
-
height: CodegenTypes.Double,
|
|
27
|
-
radius: CodegenTypes.Double
|
|
28
|
-
) => void;
|
|
29
35
|
setClipPresentation: (
|
|
30
36
|
viewRef: React.ElementRef<HostComponent<NativeProps>>,
|
|
31
37
|
x: CodegenTypes.Double,
|
|
32
38
|
y: CodegenTypes.Double,
|
|
33
39
|
width: CodegenTypes.Double,
|
|
34
40
|
height: CodegenTypes.Double,
|
|
35
|
-
|
|
41
|
+
topLeftRadius: CodegenTypes.Double,
|
|
42
|
+
topRightRadius: CodegenTypes.Double,
|
|
43
|
+
bottomRightRadius: CodegenTypes.Double,
|
|
44
|
+
bottomLeftRadius: CodegenTypes.Double,
|
|
45
|
+
curveCode: CodegenTypes.Int32,
|
|
36
46
|
contentTranslateX: CodegenTypes.Double,
|
|
37
|
-
contentTranslateY: CodegenTypes.Double
|
|
47
|
+
contentTranslateY: CodegenTypes.Double,
|
|
48
|
+
contentScale: CodegenTypes.Double,
|
|
49
|
+
shadowEnabled: boolean,
|
|
50
|
+
shadowRed: CodegenTypes.Double,
|
|
51
|
+
shadowGreen: CodegenTypes.Double,
|
|
52
|
+
shadowBlue: CodegenTypes.Double,
|
|
53
|
+
shadowAlpha: CodegenTypes.Double,
|
|
54
|
+
shadowOffsetX: CodegenTypes.Double,
|
|
55
|
+
shadowOffsetY: CodegenTypes.Double,
|
|
56
|
+
shadowBlurRadius: CodegenTypes.Double,
|
|
57
|
+
shadowSpreadDistance: CodegenTypes.Double
|
|
38
58
|
) => void;
|
|
39
59
|
}
|
|
40
60
|
|
|
41
61
|
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
42
|
-
supportedCommands: ['
|
|
62
|
+
supportedCommands: ['setClipPresentation'],
|
|
43
63
|
});
|
|
44
64
|
|
|
45
65
|
export default codegenNativeComponent<NativeProps>(
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import NativeSmoothClipModule from './smoothClipNative';
|
|
2
|
+
import type { SmoothClipCapabilities } from './capabilityTypes';
|
|
3
|
+
|
|
4
|
+
let cached: SmoothClipCapabilities | undefined;
|
|
5
|
+
|
|
6
|
+
export function getSmoothClipCapabilities(): SmoothClipCapabilities {
|
|
7
|
+
if (cached) return cached;
|
|
8
|
+
let autonomousComplexPathAnimation = false;
|
|
9
|
+
try {
|
|
10
|
+
autonomousComplexPathAnimation =
|
|
11
|
+
NativeSmoothClipModule.supportsAutonomousComplexPathAnimation() === true;
|
|
12
|
+
} catch {
|
|
13
|
+
autonomousComplexPathAnimation = false;
|
|
14
|
+
}
|
|
15
|
+
cached = {
|
|
16
|
+
autonomousComplexPathAnimation,
|
|
17
|
+
};
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SmoothClipController, SmoothClipRef } from './controllerTypes';
|
|
2
|
+
import type { CanonicalSmoothClipPresentation } from './geometry';
|
|
3
|
+
|
|
4
|
+
export type InternalSmoothClipController = Readonly<{
|
|
5
|
+
ref: SmoothClipRef;
|
|
6
|
+
initialFrame: CanonicalSmoothClipPresentation;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
export type InternalSmoothClipRef = SmoothClipRef & Readonly<{ id: number }>;
|
|
10
|
+
|
|
11
|
+
const controllers = new WeakMap<
|
|
12
|
+
SmoothClipController,
|
|
13
|
+
InternalSmoothClipController
|
|
14
|
+
>();
|
|
15
|
+
|
|
16
|
+
export function setControllerRef(
|
|
17
|
+
controller: SmoothClipController,
|
|
18
|
+
value: InternalSmoothClipController
|
|
19
|
+
): void {
|
|
20
|
+
controllers.set(controller, value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getControllerRef(
|
|
24
|
+
controller: SmoothClipController
|
|
25
|
+
): InternalSmoothClipController {
|
|
26
|
+
const value = controllers.get(controller);
|
|
27
|
+
if (!value) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
'[SmoothClipView] Controllers must be created by useSmoothClipController.'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function unwrapSmoothClipRef(
|
|
36
|
+
ref: SmoothClipRef | undefined
|
|
37
|
+
): InternalSmoothClipRef | undefined {
|
|
38
|
+
'worklet';
|
|
39
|
+
const internal = ref as InternalSmoothClipRef | undefined;
|
|
40
|
+
if (
|
|
41
|
+
internal === undefined ||
|
|
42
|
+
!Number.isSafeInteger(internal.id) ||
|
|
43
|
+
internal.id <= 0
|
|
44
|
+
) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return internal;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function createSmoothClipRef(id: number): SmoothClipRef {
|
|
51
|
+
return { id } as InternalSmoothClipRef;
|
|
52
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import NativeSmoothClipModule from './NativeSmoothClipModule';
|
|
2
|
+
|
|
3
|
+
/** Destroy from the React Native runtime; native forwards to the UI thread. */
|
|
4
|
+
export function destroyController(controllerId: number): void {
|
|
5
|
+
NativeSmoothClipModule.destroyDriver(controllerId);
|
|
6
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CanonicalSmoothClipPresentation,
|
|
3
|
+
ClipGeometry,
|
|
4
|
+
SmoothClipPresentation,
|
|
5
|
+
} from './geometry';
|
|
6
|
+
|
|
7
|
+
export type ClipReduceMotion = 'system' | 'always' | 'never';
|
|
8
|
+
|
|
9
|
+
type SmoothClipAnimationBase = Readonly<{
|
|
10
|
+
/** Resolved per transaction; it is never retained by the controller. */
|
|
11
|
+
reduceMotion?: ClipReduceMotion;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export type TimingClipAnimation = SmoothClipAnimationBase &
|
|
15
|
+
Readonly<{
|
|
16
|
+
type: 'timing';
|
|
17
|
+
duration: number;
|
|
18
|
+
controlPoints: readonly [number, number, number, number];
|
|
19
|
+
}>;
|
|
20
|
+
|
|
21
|
+
export type SpringClipAnimation = SmoothClipAnimationBase &
|
|
22
|
+
Readonly<{
|
|
23
|
+
type: 'spring';
|
|
24
|
+
mass?: number;
|
|
25
|
+
stiffness?: number;
|
|
26
|
+
damping?: number;
|
|
27
|
+
/** Normalized progress velocity in inverse seconds. */
|
|
28
|
+
velocity?: number;
|
|
29
|
+
/** Relative mechanical energy used to determine settlement. */
|
|
30
|
+
energyThreshold?: number;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
export type SmoothClipAnimation = TimingClipAnimation | SpringClipAnimation;
|
|
34
|
+
|
|
35
|
+
declare const smoothClipRefBrand: unique symbol;
|
|
36
|
+
/** Opaque, worklet-safe identity for one mounted clip host. */
|
|
37
|
+
export type SmoothClipRef = Readonly<{
|
|
38
|
+
readonly [smoothClipRefBrand]: true;
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
declare const smoothClipRunBrand: unique symbol;
|
|
42
|
+
/** Opaque identity for a native transaction started on the UI runtime. */
|
|
43
|
+
export type SmoothClipRunHandle = Readonly<{
|
|
44
|
+
readonly [smoothClipRunBrand]: true;
|
|
45
|
+
}>;
|
|
46
|
+
|
|
47
|
+
export type SmoothClipCompletion = Readonly<{
|
|
48
|
+
finished: boolean;
|
|
49
|
+
/** Present only when supplied by the UI-runtime caller. */
|
|
50
|
+
completionTag?: number;
|
|
51
|
+
}>;
|
|
52
|
+
|
|
53
|
+
export type SmoothClipReactRun = Readonly<{
|
|
54
|
+
finished: Promise<boolean>;
|
|
55
|
+
cancel(): void;
|
|
56
|
+
}>;
|
|
57
|
+
|
|
58
|
+
export type SmoothClipControllerOptions = Readonly<{
|
|
59
|
+
/** Stable React-runtime callback for UI- and React-runtime transactions. */
|
|
60
|
+
onAnimationComplete?: (result: SmoothClipCompletion) => void;
|
|
61
|
+
}>;
|
|
62
|
+
|
|
63
|
+
export type SmoothClipControllerUI = Readonly<{
|
|
64
|
+
beginInteraction(): CanonicalSmoothClipPresentation;
|
|
65
|
+
setFrame(frame: SmoothClipPresentation): void;
|
|
66
|
+
animateTo(
|
|
67
|
+
target: SmoothClipPresentation,
|
|
68
|
+
animation: SmoothClipAnimation,
|
|
69
|
+
completionTag?: number
|
|
70
|
+
): SmoothClipRunHandle | null;
|
|
71
|
+
cancel(run: SmoothClipRunHandle): CanonicalSmoothClipPresentation;
|
|
72
|
+
}>;
|
|
73
|
+
|
|
74
|
+
export type SmoothClipControllerReact = Readonly<{
|
|
75
|
+
animateTo(
|
|
76
|
+
target: SmoothClipPresentation,
|
|
77
|
+
animation: SmoothClipAnimation
|
|
78
|
+
): SmoothClipReactRun;
|
|
79
|
+
}>;
|
|
80
|
+
|
|
81
|
+
export type SmoothClipController = Readonly<{
|
|
82
|
+
ref: SmoothClipRef;
|
|
83
|
+
ui: SmoothClipControllerUI;
|
|
84
|
+
react: SmoothClipControllerReact;
|
|
85
|
+
}>;
|
|
86
|
+
|
|
87
|
+
export type SmoothClipInitialFrame = ClipGeometry | SmoothClipPresentation;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useSmoothClipController } from './controllers.native';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useSmoothClipController } from './controllers.native';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { scheduleOnUI } from 'react-native-worklets';
|
|
3
|
+
import type {
|
|
4
|
+
SmoothClipController,
|
|
5
|
+
SmoothClipControllerOptions,
|
|
6
|
+
SmoothClipInitialFrame,
|
|
7
|
+
} from './controllerTypes';
|
|
8
|
+
import { createSmoothClipRef, setControllerRef } from './controllerInternals';
|
|
9
|
+
import { destroyController } from './controllerLifecycle';
|
|
10
|
+
import { allocateSmoothClipId } from './ids';
|
|
11
|
+
import {
|
|
12
|
+
canonicalizeClipPresentation,
|
|
13
|
+
createClipPresentation,
|
|
14
|
+
type CanonicalSmoothClipPresentation,
|
|
15
|
+
} from './geometry';
|
|
16
|
+
import { useSmoothClipGroup } from './groups.native';
|
|
17
|
+
import { presentationPacket } from './presentationCodec';
|
|
18
|
+
import NativeSmoothClipModule from './smoothClipNative';
|
|
19
|
+
|
|
20
|
+
const setClipPresentationHostFunction =
|
|
21
|
+
NativeSmoothClipModule.setClipPresentation;
|
|
22
|
+
|
|
23
|
+
export function useSmoothClipController(
|
|
24
|
+
initialValue: SmoothClipInitialFrame,
|
|
25
|
+
options: SmoothClipControllerOptions = {}
|
|
26
|
+
): SmoothClipController {
|
|
27
|
+
// A controller is intentionally a one-member transaction group. This keeps
|
|
28
|
+
// validation, native dispatch, cancellation, completion, and lifecycle races
|
|
29
|
+
// on the same path as multi-member transitions.
|
|
30
|
+
const group = useSmoothClipGroup(options);
|
|
31
|
+
const initialRequested =
|
|
32
|
+
'clip' in initialValue
|
|
33
|
+
? initialValue
|
|
34
|
+
: createClipPresentation(initialValue);
|
|
35
|
+
const canonicalInitial = canonicalizeClipPresentation(initialRequested);
|
|
36
|
+
if (canonicalInitial === null) {
|
|
37
|
+
throw new Error('[SmoothClipView] Initial presentation must be finite.');
|
|
38
|
+
}
|
|
39
|
+
const initialFrameRef = useRef<CanonicalSmoothClipPresentation | null>(null);
|
|
40
|
+
initialFrameRef.current ??= canonicalInitial;
|
|
41
|
+
const initialFrame = initialFrameRef.current;
|
|
42
|
+
|
|
43
|
+
const idRef = useRef(0);
|
|
44
|
+
const controllerRef = useRef<SmoothClipController | null>(null);
|
|
45
|
+
if (idRef.current === 0) idRef.current = allocateSmoothClipId();
|
|
46
|
+
const controllerId = idRef.current;
|
|
47
|
+
|
|
48
|
+
if (controllerRef.current === null) {
|
|
49
|
+
const ref = createSmoothClipRef(controllerId);
|
|
50
|
+
const controller: SmoothClipController = {
|
|
51
|
+
ref,
|
|
52
|
+
ui: {
|
|
53
|
+
beginInteraction() {
|
|
54
|
+
'worklet';
|
|
55
|
+
return group.ui.beginInteraction([ref])[0]?.frame ?? initialFrame;
|
|
56
|
+
},
|
|
57
|
+
setFrame(frame) {
|
|
58
|
+
'worklet';
|
|
59
|
+
group.ui.setFrames([{ clip: ref, frame }]);
|
|
60
|
+
},
|
|
61
|
+
animateTo(target, animation, completionTag = 0) {
|
|
62
|
+
'worklet';
|
|
63
|
+
return group.ui.animateTo(
|
|
64
|
+
[{ clip: ref, target }],
|
|
65
|
+
animation,
|
|
66
|
+
completionTag
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
cancel(run) {
|
|
70
|
+
'worklet';
|
|
71
|
+
return group.ui.cancel(run)[0]?.frame ?? initialFrame;
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
react: {
|
|
75
|
+
animateTo(target, animation) {
|
|
76
|
+
return group.react.animateTo([{ clip: ref, target }], animation);
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
setControllerRef(controller, { ref, initialFrame });
|
|
81
|
+
controllerRef.current = controller;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
scheduleOnUI(
|
|
86
|
+
(id: number, frame: CanonicalSmoothClipPresentation) => {
|
|
87
|
+
'worklet';
|
|
88
|
+
setClipPresentationHostFunction(
|
|
89
|
+
id,
|
|
90
|
+
presentationPacket(frame),
|
|
91
|
+
true,
|
|
92
|
+
false
|
|
93
|
+
);
|
|
94
|
+
},
|
|
95
|
+
controllerId,
|
|
96
|
+
initialFrame
|
|
97
|
+
);
|
|
98
|
+
return () => {
|
|
99
|
+
destroyController(controllerId);
|
|
100
|
+
};
|
|
101
|
+
}, [controllerId, initialFrame]);
|
|
102
|
+
|
|
103
|
+
return controllerRef.current;
|
|
104
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useSmoothClipController } from './controllers.native';
|