@shopify/react-native-skia 0.1.142 → 0.1.146
Sign up to get free protection for your applications and to get access to all the features.
- package/cpp/api/JsiSkContourMeasure.h +4 -4
- package/cpp/api/JsiSkDataFactory.h +3 -3
- package/cpp/api/JsiSkFont.h +1 -1
- package/cpp/api/JsiSkPaint.h +6 -0
- package/cpp/api/JsiSkPathFactory.h +2 -2
- package/cpp/api/JsiSkPicture.h +7 -1
- package/cpp/api/JsiSkPictureFactory.h +1 -1
- package/cpp/api/JsiSkRuntimeEffect.h +6 -6
- package/cpp/api/JsiSkRuntimeEffectFactory.h +1 -1
- package/cpp/jsi/JsiSimpleValueWrapper.h +27 -27
- package/cpp/jsi/JsiValueWrapper.h +127 -0
- package/cpp/rnskia/RNSkDrawView.cpp +44 -20
- package/cpp/rnskia/RNSkDrawView.h +18 -20
- package/cpp/rnskia/RNSkJsiViewApi.h +180 -166
- package/cpp/rnskia/values/RNSkComputedValue.h +11 -11
- package/cpp/rnskia/values/RNSkReadonlyValue.h +19 -19
- package/cpp/rnskia/values/RNSkValue.h +13 -13
- package/cpp/utils/RNSkLog.h +4 -4
- package/lib/commonjs/renderer/Canvas.js +17 -7
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/renderer/DependencyManager.js +144 -36
- package/lib/commonjs/renderer/DependencyManager.js.map +1 -1
- package/lib/commonjs/renderer/HostConfig.js +18 -2
- package/lib/commonjs/renderer/HostConfig.js.map +1 -1
- package/lib/commonjs/renderer/components/Blend.js +20 -5
- package/lib/commonjs/renderer/components/Blend.js.map +1 -1
- package/lib/commonjs/renderer/components/backdrop/BackdropFilter.js.map +1 -1
- package/lib/commonjs/renderer/components/imageFilters/Morphology.js +1 -1
- package/lib/commonjs/renderer/components/imageFilters/Morphology.js.map +1 -1
- package/lib/commonjs/renderer/components/imageFilters/Shadow.js +1 -1
- package/lib/commonjs/renderer/components/imageFilters/Shadow.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Declaration.js +2 -3
- package/lib/commonjs/renderer/nodes/Declaration.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Drawing.js +3 -7
- package/lib/commonjs/renderer/nodes/Drawing.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Node.js +9 -7
- package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
- package/lib/commonjs/renderer/processors/Animations/Animations.js +3 -22
- package/lib/commonjs/renderer/processors/Animations/Animations.js.map +1 -1
- package/lib/commonjs/skia/types/Paint/Paint.js.map +1 -1
- package/lib/commonjs/skia/web/Host.js +12 -21
- package/lib/commonjs/skia/web/Host.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +46 -26
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkColorFilterFactory.js +4 -4
- package/lib/commonjs/skia/web/JsiSkColorFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkFont.js +7 -3
- package/lib/commonjs/skia/web/JsiSkFont.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImage.js +4 -2
- package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +4 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js +61 -19
- package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkMatrix.js +1 -1
- package/lib/commonjs/skia/web/JsiSkMatrix.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPaint.js +19 -6
- package/lib/commonjs/skia/web/JsiSkPaint.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPath.js +9 -55
- package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js +7 -3
- package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPathFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkPathFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPicture.js +5 -1
- package/lib/commonjs/skia/web/JsiSkPicture.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPictureRecorder.js +3 -1
- package/lib/commonjs/skia/web/JsiSkPictureRecorder.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPoint.js +9 -1
- package/lib/commonjs/skia/web/JsiSkPoint.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRRect.js +1 -1
- package/lib/commonjs/skia/web/JsiSkRRect.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRSXform.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRect.js +1 -1
- package/lib/commonjs/skia/web/JsiSkRect.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRuntimeEffect.js +4 -2
- package/lib/commonjs/skia/web/JsiSkRuntimeEffect.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkShaderFactory.js +10 -6
- package/lib/commonjs/skia/web/JsiSkShaderFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkSurface.js +3 -1
- package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkTextBlobFactory.js +8 -4
- package/lib/commonjs/skia/web/JsiSkTextBlobFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkTypefaceFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkTypefaceFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkia.js +12 -6
- package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
- package/lib/commonjs/views/SkiaView.js +11 -27
- package/lib/commonjs/views/SkiaView.js.map +1 -1
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/renderer/Canvas.js +17 -6
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/renderer/DependencyManager.js +140 -33
- package/lib/module/renderer/DependencyManager.js.map +1 -1
- package/lib/module/renderer/HostConfig.js +18 -2
- package/lib/module/renderer/HostConfig.js.map +1 -1
- package/lib/module/renderer/components/Blend.js +21 -5
- package/lib/module/renderer/components/Blend.js.map +1 -1
- package/lib/module/renderer/components/backdrop/BackdropFilter.js.map +1 -1
- package/lib/module/renderer/components/imageFilters/Morphology.js +1 -1
- package/lib/module/renderer/components/imageFilters/Morphology.js.map +1 -1
- package/lib/module/renderer/components/imageFilters/Shadow.js +1 -1
- package/lib/module/renderer/components/imageFilters/Shadow.js.map +1 -1
- package/lib/module/renderer/nodes/Declaration.js +3 -4
- package/lib/module/renderer/nodes/Declaration.js.map +1 -1
- package/lib/module/renderer/nodes/Drawing.js +3 -6
- package/lib/module/renderer/nodes/Drawing.js.map +1 -1
- package/lib/module/renderer/nodes/Node.js +9 -7
- package/lib/module/renderer/nodes/Node.js.map +1 -1
- package/lib/module/renderer/processors/Animations/Animations.js +1 -16
- package/lib/module/renderer/processors/Animations/Animations.js.map +1 -1
- package/lib/module/skia/types/Paint/Paint.js.map +1 -1
- package/lib/module/skia/web/Host.js +9 -9
- package/lib/module/skia/web/Host.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +37 -27
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/skia/web/JsiSkColorFilterFactory.js +5 -5
- package/lib/module/skia/web/JsiSkColorFilterFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkFont.js +6 -4
- package/lib/module/skia/web/JsiSkFont.js.map +1 -1
- package/lib/module/skia/web/JsiSkImage.js +4 -3
- package/lib/module/skia/web/JsiSkImage.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.js +4 -3
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFilterFactory.js +61 -20
- package/lib/module/skia/web/JsiSkImageFilterFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkMatrix.js +2 -2
- package/lib/module/skia/web/JsiSkMatrix.js.map +1 -1
- package/lib/module/skia/web/JsiSkPaint.js +15 -7
- package/lib/module/skia/web/JsiSkPaint.js.map +1 -1
- package/lib/module/skia/web/JsiSkPath.js +9 -57
- package/lib/module/skia/web/JsiSkPath.js.map +1 -1
- package/lib/module/skia/web/JsiSkPathEffectFactory.js +6 -4
- package/lib/module/skia/web/JsiSkPathEffectFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPathFactory.js +2 -2
- package/lib/module/skia/web/JsiSkPathFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPicture.js +4 -2
- package/lib/module/skia/web/JsiSkPicture.js.map +1 -1
- package/lib/module/skia/web/JsiSkPictureRecorder.js +3 -2
- package/lib/module/skia/web/JsiSkPictureRecorder.js.map +1 -1
- package/lib/module/skia/web/JsiSkPoint.js +10 -2
- package/lib/module/skia/web/JsiSkPoint.js.map +1 -1
- package/lib/module/skia/web/JsiSkRRect.js +2 -2
- package/lib/module/skia/web/JsiSkRRect.js.map +1 -1
- package/lib/module/skia/web/JsiSkRSXform.js.map +1 -1
- package/lib/module/skia/web/JsiSkRect.js +2 -2
- package/lib/module/skia/web/JsiSkRect.js.map +1 -1
- package/lib/module/skia/web/JsiSkRuntimeEffect.js +4 -3
- package/lib/module/skia/web/JsiSkRuntimeEffect.js.map +1 -1
- package/lib/module/skia/web/JsiSkShaderFactory.js +9 -7
- package/lib/module/skia/web/JsiSkShaderFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkSurface.js +3 -2
- package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/module/skia/web/JsiSkTextBlobFactory.js +7 -5
- package/lib/module/skia/web/JsiSkTextBlobFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkTypefaceFactory.js +2 -2
- package/lib/module/skia/web/JsiSkTypefaceFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkia.js +10 -5
- package/lib/module/skia/web/JsiSkia.js.map +1 -1
- package/lib/module/views/SkiaView.js +11 -26
- package/lib/module/views/SkiaView.js.map +1 -1
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/src/renderer/Canvas.d.ts +1 -1
- package/lib/typescript/src/renderer/DependencyManager.d.ts +40 -14
- package/lib/typescript/src/renderer/nodes/Declaration.d.ts +2 -2
- package/lib/typescript/src/renderer/nodes/Drawing.d.ts +2 -2
- package/lib/typescript/src/renderer/nodes/Node.d.ts +3 -2
- package/lib/typescript/src/renderer/processors/Animations/Animations.d.ts +0 -1
- package/lib/typescript/src/skia/types/Paint/Paint.d.ts +5 -0
- package/lib/typescript/src/skia/types/Picture/Picture.d.ts +2 -1
- package/lib/typescript/src/skia/web/Host.d.ts +6 -8
- package/lib/typescript/src/skia/web/JsiSkImageFilterFactory.d.ts +8 -8
- package/lib/typescript/src/skia/web/JsiSkPaint.d.ts +1 -0
- package/lib/typescript/src/skia/web/JsiSkPoint.d.ts +3 -2
- package/lib/typescript/src/skia/web/JsiSkRRect.d.ts +2 -2
- package/lib/typescript/src/skia/web/JsiSkRSXform.d.ts +1 -2
- package/lib/typescript/src/skia/web/JsiSkRect.d.ts +2 -2
- package/lib/typescript/src/skia/web/JsiSkTextBlobFactory.d.ts +2 -1
- package/lib/typescript/src/views/SkiaView.d.ts +1 -11
- package/lib/typescript/src/views/types.d.ts +5 -5
- package/libs/ios/libskia.xcframework/Info.plist +5 -5
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/package.json +2 -2
- package/src/renderer/Canvas.tsx +19 -7
- package/src/renderer/DependencyManager.tsx +170 -39
- package/src/renderer/HostConfig.ts +12 -2
- package/src/renderer/components/Blend.tsx +25 -5
- package/src/renderer/components/backdrop/BackdropFilter.tsx +1 -1
- package/src/renderer/components/imageFilters/Morphology.tsx +2 -2
- package/src/renderer/components/imageFilters/Shadow.tsx +2 -2
- package/src/renderer/nodes/Declaration.tsx +6 -8
- package/src/renderer/nodes/Drawing.tsx +5 -7
- package/src/renderer/nodes/Node.ts +11 -9
- package/src/renderer/processors/Animations/Animations.ts +2 -15
- package/src/skia/types/Paint/Paint.ts +6 -0
- package/src/skia/types/Picture/Picture.ts +2 -1
- package/src/skia/web/Host.ts +12 -22
- package/src/skia/web/JsiSkCanvas.ts +78 -47
- package/src/skia/web/JsiSkColorFilterFactory.ts +15 -5
- package/src/skia/web/JsiSkFont.ts +11 -4
- package/src/skia/web/JsiSkImage.ts +4 -3
- package/src/skia/web/JsiSkImageFactory.ts +6 -3
- package/src/skia/web/JsiSkImageFilterFactory.ts +124 -52
- package/src/skia/web/JsiSkMatrix.ts +4 -2
- package/src/skia/web/JsiSkPaint.ts +15 -7
- package/src/skia/web/JsiSkPath.ts +16 -51
- package/src/skia/web/JsiSkPathEffectFactory.ts +10 -5
- package/src/skia/web/JsiSkPathFactory.ts +3 -3
- package/src/skia/web/JsiSkPicture.ts +5 -3
- package/src/skia/web/JsiSkPictureRecorder.ts +3 -2
- package/src/skia/web/JsiSkPoint.ts +12 -2
- package/src/skia/web/JsiSkRRect.ts +5 -2
- package/src/skia/web/JsiSkRSXform.ts +1 -1
- package/src/skia/web/JsiSkRect.ts +2 -2
- package/src/skia/web/JsiSkRuntimeEffect.ts +9 -4
- package/src/skia/web/JsiSkShaderFactory.ts +24 -15
- package/src/skia/web/JsiSkSurface.ts +7 -2
- package/src/skia/web/JsiSkTextBlobFactory.ts +14 -8
- package/src/skia/web/JsiSkTypefaceFactory.tsx +4 -2
- package/src/skia/web/JsiSkia.ts +17 -5
- package/src/views/SkiaView.tsx +17 -28
- package/src/views/types.ts +7 -6
@@ -1,62 +1,193 @@
|
|
1
|
-
import type { RefObject } from "react";
|
2
|
-
|
3
|
-
import type { SkiaView } from "../views";
|
4
1
|
import type { SkiaValue } from "../values";
|
5
2
|
|
6
|
-
import { isSelector, isValue } from "./processors";
|
7
3
|
import type { Node } from "./nodes";
|
4
|
+
import type { AnimatedProps } from "./processors";
|
5
|
+
import { isSelector, isValue } from "./processors";
|
6
|
+
import { mapKeys } from "./typeddash";
|
8
7
|
|
9
8
|
type Unsubscribe = () => void;
|
10
|
-
type
|
9
|
+
type Mutator = (value: unknown) => void;
|
10
|
+
|
11
|
+
type SubscriptionState = {
|
12
|
+
nodes: Map<Node, Mutator[]>;
|
13
|
+
unsubscribe: null | Unsubscribe;
|
14
|
+
};
|
11
15
|
|
12
16
|
export class DependencyManager {
|
13
|
-
|
14
|
-
subscriptions: Map<
|
15
|
-
|
16
|
-
{ values: SkiaValue<unknown>[]; unsubscribe: null | Unsubscribe }
|
17
|
-
> = new Map();
|
18
|
-
|
19
|
-
constructor(ref: RefObject<SkiaView>) {
|
20
|
-
this.ref = ref;
|
21
|
-
}
|
17
|
+
registerValues: (values: Array<SkiaValue<unknown>>) => () => void;
|
18
|
+
subscriptions: Map<SkiaValue<unknown>, SubscriptionState> = new Map();
|
19
|
+
unregisterDependantValues: null | Unsubscribe = null;
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
28
|
-
this.subscriptions.delete(node);
|
21
|
+
constructor(
|
22
|
+
registerValues: (values: Array<SkiaValue<unknown>>) => () => void
|
23
|
+
) {
|
24
|
+
this.registerValues = registerValues;
|
29
25
|
}
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
/**
|
28
|
+
* Call to unsubscribe all value listeners from the given node based
|
29
|
+
* on the current list of subscriptions for the node. This function
|
30
|
+
* is typically called when the node is unmounted or when one or more
|
31
|
+
* properties have changed.
|
32
|
+
* @param node Node to unsubscribe value listeners from
|
33
|
+
*/
|
34
|
+
unsubscribeNode(node: Node) {
|
35
|
+
const subscriptions = Array.from(this.subscriptions.values()).filter((p) =>
|
36
|
+
p.nodes.has(node)
|
37
|
+
);
|
35
38
|
|
36
|
-
if (
|
37
|
-
|
39
|
+
if (subscriptions) {
|
40
|
+
subscriptions.forEach((si) => {
|
41
|
+
// Delete node from subscription
|
42
|
+
si.nodes.delete(node);
|
43
|
+
|
44
|
+
// Remove subscription if there are no listeneres left on the value
|
45
|
+
if (si.nodes.size === 0) {
|
46
|
+
// There are no more nodes subscribing to this value, we can call
|
47
|
+
// unsubscribe on it.
|
48
|
+
if (!si.unsubscribe) {
|
49
|
+
throw new Error("Failed to unsubscribe to value subscription");
|
50
|
+
}
|
51
|
+
si.unsubscribe && si.unsubscribe();
|
52
|
+
|
53
|
+
// Remove from subscription states as well
|
54
|
+
const element = Array.from(this.subscriptions.entries()).find(
|
55
|
+
([_, sub]) => sub === si
|
56
|
+
);
|
57
|
+
if (!element) {
|
58
|
+
throw new Error("Failed to find value subscription");
|
59
|
+
}
|
60
|
+
if (!this.subscriptions.delete(element[0])) {
|
61
|
+
throw new Error("Failed to delete value subscription");
|
62
|
+
}
|
63
|
+
}
|
64
|
+
});
|
38
65
|
}
|
39
66
|
}
|
40
67
|
|
41
|
-
|
42
|
-
|
43
|
-
|
68
|
+
/**
|
69
|
+
* Adds listeners to the provided values so that the node is notified
|
70
|
+
* when a value changes. This is done in an optimized way so that this
|
71
|
+
* class only needs to listen to the value once and then forwards the
|
72
|
+
* change to the node and its listener. This method is typically called
|
73
|
+
* when the node is mounted and when one or more props on the node changes.
|
74
|
+
* @param node Node to subscribe to value changes for
|
75
|
+
* @param props Node's properties
|
76
|
+
* @param onResolveProp Callback when a property value changes
|
77
|
+
*/
|
78
|
+
subscribeNode<P extends Record<string, unknown>>(
|
79
|
+
node: Node,
|
80
|
+
props: AnimatedProps<P>
|
81
|
+
) {
|
82
|
+
// Get mutators from node's properties
|
83
|
+
const propSubscriptions = initializePropertySubscriptions(node, props);
|
84
|
+
if (propSubscriptions.length === 0) {
|
85
|
+
return;
|
44
86
|
}
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
87
|
+
|
88
|
+
// Install all mutators for the node
|
89
|
+
propSubscriptions.forEach((ps) => {
|
90
|
+
// Do we already have a state for this SkiaValue
|
91
|
+
let subscriptionState = this.subscriptions.get(ps.value);
|
92
|
+
if (!subscriptionState) {
|
93
|
+
// Let's create a new subscription state for the skia value
|
94
|
+
subscriptionState = {
|
95
|
+
nodes: new Map(),
|
96
|
+
unsubscribe: null,
|
97
|
+
};
|
98
|
+
// Add single subscription to the new value
|
99
|
+
subscriptionState.unsubscribe = ps.value.addListener((v) => {
|
100
|
+
subscriptionState!.nodes.forEach((mutators) =>
|
101
|
+
mutators.forEach((m) => m(v))
|
102
|
+
);
|
103
|
+
});
|
104
|
+
this.subscriptions.set(ps.value, subscriptionState);
|
50
105
|
}
|
106
|
+
// subscription mutators
|
107
|
+
subscriptionState.nodes.set(
|
108
|
+
node,
|
109
|
+
propSubscriptions
|
110
|
+
.filter((m) => m.value === ps.value)
|
111
|
+
.map((m) => m.mutator)
|
112
|
+
);
|
51
113
|
});
|
52
114
|
}
|
53
115
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
116
|
+
/**
|
117
|
+
* Called when the hosting container is mounted or updated. This ensures that we have
|
118
|
+
* a ref to the underlying SkiaView so that we can registers redraw listeners
|
119
|
+
* on values used in the current View automatically.
|
120
|
+
*/
|
121
|
+
update() {
|
122
|
+
// Remove any previous registrations
|
123
|
+
if (this.unregisterDependantValues) {
|
124
|
+
this.unregisterDependantValues();
|
125
|
+
}
|
126
|
+
|
127
|
+
// Register redraw requests on the SkiaView for each unique value
|
128
|
+
this.unregisterDependantValues = this.registerValues(
|
129
|
+
Array.from(this.subscriptions.keys())
|
130
|
+
);
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Called when the hosting container is unmounted or recreated. This ensures that we remove
|
135
|
+
* all subscriptions to Skia values so that we don't have any listeners left after
|
136
|
+
* the component is removed.
|
137
|
+
*/
|
138
|
+
remove() {
|
139
|
+
// 1) Unregister redraw requests
|
140
|
+
if (this.unregisterDependantValues) {
|
141
|
+
this.unregisterDependantValues();
|
142
|
+
this.unregisterDependantValues = null;
|
143
|
+
}
|
144
|
+
|
145
|
+
// 2) Unregister nodes
|
146
|
+
Array.from(this.subscriptions.values()).forEach((si) => {
|
147
|
+
Array.from(si.nodes.keys()).forEach((node) => this.unsubscribeNode(node));
|
59
148
|
});
|
149
|
+
|
150
|
+
// 3) Clear the rest of the subscriptions
|
60
151
|
this.subscriptions.clear();
|
61
152
|
}
|
62
153
|
}
|
154
|
+
|
155
|
+
const initializePropertySubscriptions = <P,>(
|
156
|
+
node: Node<P>,
|
157
|
+
props: AnimatedProps<P>
|
158
|
+
) => {
|
159
|
+
const nodePropSubscriptions: Array<{
|
160
|
+
value: SkiaValue<unknown>;
|
161
|
+
mutator: Mutator;
|
162
|
+
}> = [];
|
163
|
+
|
164
|
+
mapKeys(props).forEach((key) => {
|
165
|
+
const propvalue = props[key];
|
166
|
+
|
167
|
+
if (isValue(propvalue)) {
|
168
|
+
// Subscribe to changes
|
169
|
+
nodePropSubscriptions.push({
|
170
|
+
value: propvalue,
|
171
|
+
mutator: (v) => (node.resolvedProps[key] = v as P[typeof key]),
|
172
|
+
});
|
173
|
+
// Set initial value
|
174
|
+
node.resolvedProps[key] = (propvalue as SkiaValue<P[typeof key]>).current;
|
175
|
+
} else if (isSelector(propvalue)) {
|
176
|
+
// Subscribe to changes
|
177
|
+
nodePropSubscriptions.push({
|
178
|
+
value: propvalue.value,
|
179
|
+
mutator: (v) =>
|
180
|
+
(node.resolvedProps[key] = propvalue.selector(v) as P[typeof key]),
|
181
|
+
});
|
182
|
+
// Set initial value
|
183
|
+
node.resolvedProps[key] = propvalue.selector(
|
184
|
+
propvalue.value.current
|
185
|
+
) as P[typeof key];
|
186
|
+
} else {
|
187
|
+
// Set initial value
|
188
|
+
node.resolvedProps[key] = propvalue as P[typeof key];
|
189
|
+
}
|
190
|
+
});
|
191
|
+
|
192
|
+
return nodePropSubscriptions;
|
193
|
+
};
|
@@ -101,7 +101,7 @@ const removeNode = (parent: Node, child: Node) => {
|
|
101
101
|
bustBranchMemoization(parent);
|
102
102
|
const index = parent.children.indexOf(child);
|
103
103
|
parent.children.splice(index, 1);
|
104
|
-
child.depMgr.
|
104
|
+
child.depMgr.unsubscribeNode(child);
|
105
105
|
// unsubscribe to all children as well
|
106
106
|
for (const c of child.children) {
|
107
107
|
removeNode(child, c);
|
@@ -265,7 +265,17 @@ export const skHostConfig: SkiaHostConfig = {
|
|
265
265
|
return;
|
266
266
|
}
|
267
267
|
bustBranchMemoization(instance);
|
268
|
-
instance
|
268
|
+
if (instance instanceof DrawingNode) {
|
269
|
+
const { onDraw, skipProcessing, ...props } = nextProps;
|
270
|
+
instance.props = props;
|
271
|
+
} else if (instance instanceof DeclarationNode) {
|
272
|
+
const { onDeclare, ...props } = nextProps;
|
273
|
+
instance.props = props;
|
274
|
+
} else {
|
275
|
+
throw new Error(
|
276
|
+
"Unsupported instance commitUpdate " + instance.constructor.name
|
277
|
+
);
|
278
|
+
}
|
269
279
|
},
|
270
280
|
|
271
281
|
commitTextUpdate: (
|
@@ -1,10 +1,21 @@
|
|
1
1
|
import type { ReactNode } from "react";
|
2
2
|
import React from "react";
|
3
3
|
|
4
|
+
import type { SkImageFilter, SkShader } from "../../skia/types";
|
4
5
|
import { isImageFilter, BlendMode, isShader } from "../../skia/types";
|
5
6
|
import { createDeclaration } from "../nodes";
|
6
7
|
import type { AnimatedProps, SkEnum } from "../processors";
|
7
8
|
import { enumKey } from "../processors/Paint";
|
9
|
+
import type { DeclarationResult } from "../nodes/Declaration";
|
10
|
+
|
11
|
+
const childrenAreImageFilters = (
|
12
|
+
children: DeclarationResult[]
|
13
|
+
): children is SkImageFilter[] =>
|
14
|
+
children.every((child) => isImageFilter(child));
|
15
|
+
|
16
|
+
const childrenAreShaders = (
|
17
|
+
children: DeclarationResult[]
|
18
|
+
): children is SkShader[] => children.every((child) => isShader(child));
|
8
19
|
|
9
20
|
interface BlendProps {
|
10
21
|
mode: SkEnum<typeof BlendMode>;
|
@@ -13,12 +24,21 @@ interface BlendProps {
|
|
13
24
|
|
14
25
|
const onDeclare = createDeclaration<BlendProps>(
|
15
26
|
({ mode }, children, { Skia }) => {
|
16
|
-
const [inner, outer] = children;
|
17
27
|
const blend = BlendMode[enumKey(mode)];
|
18
|
-
if (
|
19
|
-
return
|
20
|
-
|
21
|
-
|
28
|
+
if (childrenAreImageFilters(children)) {
|
29
|
+
return children.reverse().reduce<SkImageFilter | null>((inner, outer) => {
|
30
|
+
if (inner === null) {
|
31
|
+
return outer;
|
32
|
+
}
|
33
|
+
return Skia.ImageFilter.MakeBlend(blend, outer, inner);
|
34
|
+
}, null);
|
35
|
+
} else if (childrenAreShaders(children)) {
|
36
|
+
return children.reverse().reduce<SkShader | null>((inner, outer) => {
|
37
|
+
if (inner === null) {
|
38
|
+
return outer;
|
39
|
+
}
|
40
|
+
return Skia.Shader.MakeBlend(blend, outer, inner);
|
41
|
+
}, null);
|
22
42
|
}
|
23
43
|
throw new Error("<Blend /> can only blend Shaders or ImageFilters");
|
24
44
|
}
|
@@ -8,7 +8,7 @@ import { getInput } from "../imageFilters/getInput";
|
|
8
8
|
import type { GroupProps } from "../Group";
|
9
9
|
import { Group } from "../Group";
|
10
10
|
|
11
|
-
const disableFilterMemoization = (children: Node
|
11
|
+
const disableFilterMemoization = (children: Node[]) => {
|
12
12
|
children.forEach((child) => {
|
13
13
|
child.memoizable = false;
|
14
14
|
disableFilterMemoization(child.children);
|
@@ -18,8 +18,8 @@ const onDeclare = createDeclaration<MorphologyProps>(
|
|
18
18
|
const r = processRadius(Skia, radius);
|
19
19
|
const factory =
|
20
20
|
operator === "dilate"
|
21
|
-
? Skia.ImageFilter.MakeDilate
|
22
|
-
: Skia.ImageFilter.MakeErode;
|
21
|
+
? Skia.ImageFilter.MakeDilate.bind(Skia.ImageFilter)
|
22
|
+
: Skia.ImageFilter.MakeErode.bind(Skia.ImageFilter);
|
23
23
|
return factory(r.x, r.y, input);
|
24
24
|
}
|
25
25
|
);
|
@@ -30,8 +30,8 @@ const onDeclare = createDeclaration<ShadowProps>(
|
|
30
30
|
factory = MakeInnerShadow.bind(null, Skia, shadowOnly);
|
31
31
|
} else {
|
32
32
|
factory = shadowOnly
|
33
|
-
? Skia.ImageFilter.MakeDropShadowOnly
|
34
|
-
: Skia.ImageFilter.MakeDropShadow;
|
33
|
+
? Skia.ImageFilter.MakeDropShadowOnly.bind(Skia.ImageFilter)
|
34
|
+
: Skia.ImageFilter.MakeDropShadow.bind(Skia.ImageFilter);
|
35
35
|
}
|
36
36
|
return factory(dx, dy, blur, blur, color, input);
|
37
37
|
}
|
@@ -3,7 +3,7 @@ import { useCallback } from "react";
|
|
3
3
|
|
4
4
|
import type { DrawingContext } from "../DrawingContext";
|
5
5
|
import type { AnimatedProps } from "../processors";
|
6
|
-
import { isAnimated
|
6
|
+
import { isAnimated } from "../processors";
|
7
7
|
import type { DependencyManager } from "../DependencyManager";
|
8
8
|
import type { SkJSIInstance } from "../../skia/types";
|
9
9
|
|
@@ -28,9 +28,8 @@ export const useDeclaration = <P,>(
|
|
28
28
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
29
29
|
useCallback(cb, deps ?? []);
|
30
30
|
|
31
|
-
export const isDeclarationNode = (
|
32
|
-
node
|
33
|
-
): node is DeclarationNode<unknown> => node instanceof DeclarationNode;
|
31
|
+
export const isDeclarationNode = <P,>(node: Node): node is DeclarationNode<P> =>
|
32
|
+
node instanceof DeclarationNode;
|
34
33
|
|
35
34
|
export interface DeclarationProps<P> {
|
36
35
|
onDeclare: DeclarationCallback<P>;
|
@@ -54,14 +53,13 @@ export class DeclarationNode<P> extends Node<P> {
|
|
54
53
|
super.props = props;
|
55
54
|
}
|
56
55
|
|
57
|
-
get props() {
|
58
|
-
return this.
|
56
|
+
get props(): P {
|
57
|
+
return this.resolvedProps;
|
59
58
|
}
|
60
59
|
|
61
60
|
draw(ctx: DrawingContext) {
|
62
61
|
const children = this.visit(ctx);
|
63
|
-
const
|
64
|
-
const obj = this.onDeclare(props, children, ctx);
|
62
|
+
const obj = this.onDeclare(this.props, children, ctx);
|
65
63
|
return obj;
|
66
64
|
}
|
67
65
|
}
|
@@ -3,7 +3,6 @@ import { useCallback } from "react";
|
|
3
3
|
|
4
4
|
import type { DrawingContext } from "../DrawingContext";
|
5
5
|
import type { AnimatedProps } from "../processors/Animations/Animations";
|
6
|
-
import { materialize } from "../processors/Animations/Animations";
|
7
6
|
import { isPaint } from "../../skia/types";
|
8
7
|
import type { DependencyManager } from "../DependencyManager";
|
9
8
|
import { processPaint } from "../processors";
|
@@ -25,8 +24,8 @@ export const useDrawing = <P,>(cb: OnDrawCallback<P>, deps?: DependencyList) =>
|
|
25
24
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
26
25
|
useCallback(cb, deps ?? []);
|
27
26
|
|
28
|
-
export type DrawingProps<
|
29
|
-
onDraw: DrawingCallback<
|
27
|
+
export type DrawingProps<P> = {
|
28
|
+
onDraw: DrawingCallback<P>;
|
30
29
|
skipProcessing?: boolean;
|
31
30
|
children?: ReactNode | ReactNode[];
|
32
31
|
};
|
@@ -47,20 +46,19 @@ export class DrawingNode<P> extends Node<P> {
|
|
47
46
|
}
|
48
47
|
|
49
48
|
draw(ctx: DrawingContext) {
|
50
|
-
const drawingProps = materialize(this.props);
|
51
49
|
if (this.skipProcessing) {
|
52
|
-
this.onDraw(ctx,
|
50
|
+
this.onDraw(ctx, this.props, this);
|
53
51
|
} else {
|
54
52
|
const declarations = this.visit(ctx);
|
55
53
|
const paint = processPaint(
|
56
54
|
ctx.Skia,
|
57
55
|
ctx.paint.copy(),
|
58
56
|
ctx.opacity,
|
59
|
-
|
57
|
+
this.props,
|
60
58
|
declarations
|
61
59
|
);
|
62
60
|
[paint, ...declarations.filter(isPaint)].forEach((currentPaint) => {
|
63
|
-
this.onDraw({ ...ctx, paint: currentPaint },
|
61
|
+
this.onDraw({ ...ctx, paint: currentPaint }, this.props, this);
|
64
62
|
});
|
65
63
|
}
|
66
64
|
}
|
@@ -12,29 +12,31 @@ type DeclarationResult = SkJSIInstance<string> | null;
|
|
12
12
|
|
13
13
|
export abstract class Node<P = unknown> {
|
14
14
|
readonly children: Node[] = [];
|
15
|
-
|
15
|
+
// This cast is ok because we understand that the dependency manager will setup the initial props
|
16
|
+
resolvedProps: P = {} as P;
|
16
17
|
memoizable = false;
|
17
18
|
memoized: DeclarationResult | null = null;
|
18
19
|
parent?: Node;
|
19
20
|
depMgr: DependencyManager;
|
20
21
|
|
21
22
|
constructor(depMgr: DependencyManager, props: AnimatedProps<P>) {
|
22
|
-
this._props = props;
|
23
23
|
this.depMgr = depMgr;
|
24
|
-
this.
|
25
|
-
this.depMgr.subscribeNode(this, props);
|
24
|
+
this.updatePropSubscriptions(props);
|
26
25
|
}
|
27
26
|
|
28
27
|
abstract draw(ctx: DrawingContext): void | DeclarationResult;
|
29
28
|
|
30
|
-
|
31
|
-
this.depMgr.unSubscribeNode(this);
|
29
|
+
updatePropSubscriptions(props: AnimatedProps<P>) {
|
32
30
|
this.depMgr.subscribeNode(this, props);
|
33
|
-
this._props = props;
|
34
31
|
}
|
35
32
|
|
36
|
-
|
37
|
-
|
33
|
+
set props(props: AnimatedProps<P>) {
|
34
|
+
this.depMgr.unsubscribeNode(this);
|
35
|
+
this.updatePropSubscriptions(props);
|
36
|
+
}
|
37
|
+
|
38
|
+
get props(): P {
|
39
|
+
return this.resolvedProps;
|
38
40
|
}
|
39
41
|
|
40
42
|
visit(ctx: DrawingContext, children?: Node[]) {
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import type { SkiaSelector, SkiaValue } from "../../../values";
|
2
|
-
import { mapKeys } from "../../typeddash";
|
3
2
|
|
4
3
|
export const isValue = (value: unknown): value is SkiaValue<unknown> => {
|
5
4
|
if (value === undefined || value === null) {
|
@@ -37,28 +36,16 @@ export const isSelector = <T, R>(
|
|
37
36
|
|
38
37
|
export const isAnimated = <T>(props: AnimatedProps<T>) => {
|
39
38
|
for (const value of Object.values(props)) {
|
40
|
-
if (isValue(value)) {
|
39
|
+
if (isValue(value) || isSelector(value)) {
|
41
40
|
return true;
|
42
41
|
}
|
43
42
|
}
|
44
43
|
return false;
|
45
44
|
};
|
46
45
|
|
47
|
-
export const materialize = <T>(props: AnimatedProps<T>) => {
|
48
|
-
const result = { ...props };
|
49
|
-
mapKeys(props).forEach((key) => {
|
50
|
-
const prop = props[key];
|
51
|
-
if (isValue(prop)) {
|
52
|
-
result[key] = (prop as SkiaValue<T[typeof key]>).current;
|
53
|
-
} else if (isSelector(prop)) {
|
54
|
-
result[key] = prop.selector(prop.value.current) as T[typeof key];
|
55
|
-
}
|
56
|
-
});
|
57
|
-
return result as T;
|
58
|
-
};
|
59
|
-
|
60
46
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
61
47
|
export type AnimatedProp<T, P = any> = T | SkiaValue<T> | SkiaSelector<T, P>;
|
48
|
+
|
62
49
|
export type AnimatedProps<T> = {
|
63
50
|
[K in keyof T]: AnimatedProp<T[K]>;
|
64
51
|
};
|
@@ -34,6 +34,12 @@ export interface SkPaint extends SkJSIInstance<"Paint"> {
|
|
34
34
|
*/
|
35
35
|
copy(): SkPaint;
|
36
36
|
|
37
|
+
/**
|
38
|
+
* Sets all SkPaint contents to their initial values. This is equivalent to replacing
|
39
|
+
SkPaint with the result of SkPaint().
|
40
|
+
*/
|
41
|
+
reset(): void;
|
42
|
+
|
37
43
|
/**
|
38
44
|
* Retrieves the alpha and RGB unpremultiplied. RGB are extended sRGB values
|
39
45
|
* (sRGB gamut, and encoded with the sRGB transfer function).
|
@@ -3,8 +3,9 @@ import type { TileMode } from "../ImageFilter";
|
|
3
3
|
import type { SkRect } from "../Rect";
|
4
4
|
import type { SkShader } from "../Shader";
|
5
5
|
import type { SkMatrix } from "../Matrix";
|
6
|
+
import type { SkJSIInstance } from "../JsiInstance";
|
6
7
|
|
7
|
-
export interface SkPicture {
|
8
|
+
export interface SkPicture extends SkJSIInstance<"Picture"> {
|
8
9
|
/**
|
9
10
|
* Returns a new shader that will draw with this picture.
|
10
11
|
*
|
package/src/skia/web/Host.ts
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
/* eslint-disable no-nested-ternary */
|
2
1
|
import type { CanvasKit, EmbindEnumEntity } from "canvaskit-wasm";
|
3
2
|
|
4
3
|
import type { SkJSIInstance } from "../types";
|
5
4
|
|
6
5
|
export class NotImplementedOnRNWeb extends Error {
|
7
|
-
constructor() {
|
8
|
-
super("Not implemented on React Native Web");
|
6
|
+
constructor(msg?: string) {
|
7
|
+
super(msg ?? "Not implemented on React Native Web");
|
9
8
|
}
|
10
9
|
}
|
11
10
|
|
@@ -17,12 +16,12 @@ export abstract class Host {
|
|
17
16
|
}
|
18
17
|
}
|
19
18
|
|
20
|
-
export abstract class
|
19
|
+
export abstract class BaseHostObject<T, N extends string>
|
21
20
|
extends Host
|
22
21
|
implements SkJSIInstance<N>
|
23
22
|
{
|
24
23
|
readonly __typename__: N;
|
25
|
-
|
24
|
+
ref: T;
|
26
25
|
|
27
26
|
constructor(CanvasKit: CanvasKit, ref: T, typename: N) {
|
28
27
|
super(CanvasKit);
|
@@ -31,23 +30,14 @@ export abstract class HostObject<T, N extends string>
|
|
31
30
|
}
|
32
31
|
}
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
value:
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
export const toUndefinedableValue = <T>(
|
43
|
-
value: NonNullish | undefined
|
44
|
-
): T | undefined => (value === undefined ? undefined : toValue(value));
|
45
|
-
|
46
|
-
export const toNullableValue = <T>(value: NonNullish | null): T | null =>
|
47
|
-
value === null ? null : toValue(value);
|
48
|
-
|
49
|
-
export const toValue = <T>(value: NonNullish): T =>
|
50
|
-
(value as HostObject<T, string>).ref;
|
33
|
+
export abstract class HostObject<T, N extends string> extends BaseHostObject<
|
34
|
+
T,
|
35
|
+
N
|
36
|
+
> {
|
37
|
+
static fromValue<T>(value: SkJSIInstance<string>) {
|
38
|
+
return (value as HostObject<T, string>).ref;
|
39
|
+
}
|
40
|
+
}
|
51
41
|
|
52
42
|
export const ckEnum = (value: number): EmbindEnumEntity => ({ value });
|
53
43
|
export const optEnum = (
|