@shopify/react-native-skia 0.1.116 → 0.1.118
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/cpp/api/JsiSkApi.h +13 -9
- package/cpp/api/JsiSkCanvas.h +9 -1
- package/cpp/api/JsiSkPicture.h +71 -0
- package/cpp/api/JsiSkPictureFactory.h +50 -0
- package/cpp/api/JsiSkPictureRecorder.h +53 -0
- package/lib/commonjs/renderer/Canvas.js +22 -36
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/renderer/HostConfig.js +2 -24
- package/lib/commonjs/renderer/HostConfig.js.map +1 -1
- package/lib/commonjs/renderer/components/Drawing.js +31 -0
- package/lib/commonjs/renderer/components/Drawing.js.map +1 -0
- package/lib/commonjs/renderer/components/Group.js +1 -1
- package/lib/commonjs/renderer/components/Group.js.map +1 -1
- package/lib/commonjs/renderer/components/Picture.js +35 -0
- package/lib/commonjs/renderer/components/Picture.js.map +1 -0
- package/lib/commonjs/renderer/components/imageFilters/InnerShadow.js +5 -34
- package/lib/commonjs/renderer/components/imageFilters/InnerShadow.js.map +1 -1
- package/lib/commonjs/renderer/components/imageFilters/{DropShadow.js → Shadow.js} +19 -8
- package/lib/commonjs/renderer/components/imageFilters/Shadow.js.map +1 -0
- package/lib/commonjs/renderer/components/imageFilters/index.js +4 -17
- package/lib/commonjs/renderer/components/imageFilters/index.js.map +1 -1
- package/lib/commonjs/renderer/components/index.js +26 -0
- package/lib/commonjs/renderer/components/index.js.map +1 -1
- package/lib/commonjs/renderer/components/maskFilters/Blur.js +1 -1
- package/lib/commonjs/renderer/components/maskFilters/Blur.js.map +1 -1
- package/lib/commonjs/renderer/components/shapes/Box.js +126 -0
- package/lib/commonjs/renderer/components/shapes/Box.js.map +1 -0
- package/lib/commonjs/renderer/components/shapes/index.js +13 -0
- package/lib/commonjs/renderer/components/shapes/index.js.map +1 -1
- package/lib/commonjs/renderer/index.js +13 -0
- package/lib/commonjs/renderer/index.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Declaration.js +8 -1
- package/lib/commonjs/renderer/nodes/Declaration.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Drawing.js +5 -8
- package/lib/commonjs/renderer/nodes/Drawing.js.map +1 -1
- package/lib/commonjs/renderer/processors/math/Math.js +19 -1
- package/lib/commonjs/renderer/processors/math/Math.js.map +1 -1
- package/lib/commonjs/renderer/processors/math/Matrix3.js +11 -5
- package/lib/commonjs/renderer/processors/math/Matrix3.js.map +1 -1
- package/lib/commonjs/renderer/typeddash.js +26 -2
- package/lib/commonjs/renderer/typeddash.js.map +1 -1
- package/lib/commonjs/renderer/useContextBridge.js +35 -0
- package/lib/commonjs/renderer/useContextBridge.js.map +1 -0
- package/lib/commonjs/skia/Canvas.js.map +1 -1
- package/lib/commonjs/skia/Picture/Picture.js +6 -0
- package/lib/commonjs/skia/Picture/Picture.js.map +1 -0
- package/lib/commonjs/skia/Picture/PictureFactory.js +6 -0
- package/lib/commonjs/skia/Picture/PictureFactory.js.map +1 -0
- package/lib/commonjs/skia/Picture/PictureRecorder.js +6 -0
- package/lib/commonjs/skia/Picture/PictureRecorder.js.map +1 -0
- package/lib/commonjs/skia/Picture/index.js +58 -0
- package/lib/commonjs/skia/Picture/index.js.map +1 -0
- package/lib/commonjs/skia/Picture/usePicture.js +30 -0
- package/lib/commonjs/skia/Picture/usePicture.js.map +1 -0
- package/lib/commonjs/skia/Skia.js +2 -0
- package/lib/commonjs/skia/Skia.js.map +1 -1
- package/lib/commonjs/skia/index.js +14 -0
- package/lib/commonjs/skia/index.js.map +1 -1
- package/lib/commonjs/values/hooks/useDerivedValue.js +2 -2
- package/lib/commonjs/values/hooks/useDerivedValue.js.map +1 -1
- package/lib/commonjs/views/SkiaView.js +6 -5
- package/lib/commonjs/views/SkiaView.js.map +1 -1
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/renderer/Canvas.js +20 -32
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/renderer/HostConfig.js +1 -23
- package/lib/module/renderer/HostConfig.js.map +1 -1
- package/lib/module/renderer/components/Drawing.js +17 -0
- package/lib/module/renderer/components/Drawing.js.map +1 -0
- package/lib/module/renderer/components/Group.js +1 -1
- package/lib/module/renderer/components/Group.js.map +1 -1
- package/lib/module/renderer/components/Picture.js +21 -0
- package/lib/module/renderer/components/Picture.js.map +1 -0
- package/lib/module/renderer/components/imageFilters/InnerShadow.js +4 -26
- package/lib/module/renderer/components/imageFilters/InnerShadow.js.map +1 -1
- package/lib/module/renderer/components/imageFilters/{DropShadow.js → Shadow.js} +16 -6
- package/lib/module/renderer/components/imageFilters/Shadow.js.map +1 -0
- package/lib/module/renderer/components/imageFilters/index.js +1 -2
- package/lib/module/renderer/components/imageFilters/index.js.map +1 -1
- package/lib/module/renderer/components/index.js +2 -0
- package/lib/module/renderer/components/index.js.map +1 -1
- package/lib/module/renderer/components/maskFilters/Blur.js +1 -1
- package/lib/module/renderer/components/maskFilters/Blur.js.map +1 -1
- package/lib/module/renderer/components/shapes/Box.js +102 -0
- package/lib/module/renderer/components/shapes/Box.js.map +1 -0
- package/lib/module/renderer/components/shapes/index.js +1 -0
- package/lib/module/renderer/components/shapes/index.js.map +1 -1
- package/lib/module/renderer/index.js +1 -0
- package/lib/module/renderer/index.js.map +1 -1
- package/lib/module/renderer/nodes/Declaration.js +3 -0
- package/lib/module/renderer/nodes/Declaration.js.map +1 -1
- package/lib/module/renderer/nodes/Drawing.js +3 -4
- package/lib/module/renderer/nodes/Drawing.js.map +1 -1
- package/lib/module/renderer/processors/math/Math.js +15 -0
- package/lib/module/renderer/processors/math/Math.js.map +1 -1
- package/lib/module/renderer/processors/math/Matrix3.js +6 -2
- package/lib/module/renderer/processors/math/Matrix3.js.map +1 -1
- package/lib/module/renderer/typeddash.js +21 -0
- package/lib/module/renderer/typeddash.js.map +1 -1
- package/lib/module/renderer/useContextBridge.js +21 -0
- package/lib/module/renderer/useContextBridge.js.map +1 -0
- package/lib/module/skia/Canvas.js.map +1 -1
- package/lib/module/skia/Picture/Picture.js +2 -0
- package/lib/module/skia/Picture/Picture.js.map +1 -0
- package/lib/module/skia/Picture/PictureFactory.js +2 -0
- package/lib/module/skia/Picture/PictureFactory.js.map +1 -0
- package/lib/module/skia/Picture/PictureRecorder.js +2 -0
- package/lib/module/skia/Picture/PictureRecorder.js.map +1 -0
- package/lib/module/skia/Picture/index.js +5 -0
- package/lib/module/skia/Picture/index.js.map +1 -0
- package/lib/module/skia/Picture/usePicture.js +19 -0
- package/lib/module/skia/Picture/usePicture.js.map +1 -0
- package/lib/module/skia/Skia.js +2 -0
- package/lib/module/skia/Skia.js.map +1 -1
- package/lib/module/skia/index.js +1 -0
- package/lib/module/skia/index.js.map +1 -1
- package/lib/module/values/hooks/useDerivedValue.js +1 -1
- package/lib/module/values/hooks/useDerivedValue.js.map +1 -1
- package/lib/module/views/SkiaView.js +6 -5
- 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 +5 -10
- package/lib/typescript/src/renderer/components/Drawing.d.ts +7 -0
- package/lib/typescript/src/renderer/components/Picture.d.ts +6 -0
- package/lib/typescript/src/renderer/components/imageFilters/InnerShadow.d.ts +3 -12
- package/lib/typescript/src/renderer/components/imageFilters/{DropShadow.d.ts → Shadow.d.ts} +3 -2
- package/lib/typescript/src/renderer/components/imageFilters/index.d.ts +1 -2
- package/lib/typescript/src/renderer/components/index.d.ts +2 -0
- package/lib/typescript/src/renderer/components/shapes/Box.d.ts +23 -0
- package/lib/typescript/src/renderer/components/shapes/index.d.ts +1 -0
- package/lib/typescript/src/renderer/index.d.ts +1 -0
- package/lib/typescript/src/renderer/nodes/Declaration.d.ts +2 -0
- package/lib/typescript/src/renderer/nodes/Drawing.d.ts +2 -2
- package/lib/typescript/src/renderer/processors/math/Math.d.ts +14 -0
- package/lib/typescript/src/renderer/processors/math/Matrix3.d.ts +1 -0
- package/lib/typescript/src/renderer/typeddash.d.ts +1 -0
- package/lib/typescript/src/renderer/useContextBridge.d.ts +5 -0
- package/lib/typescript/src/skia/Canvas.d.ts +6 -0
- package/lib/typescript/src/skia/Picture/Picture.d.ts +26 -0
- package/lib/typescript/src/skia/Picture/PictureFactory.d.ts +8 -0
- package/lib/typescript/src/skia/Picture/PictureRecorder.d.ts +15 -0
- package/lib/typescript/src/skia/Picture/index.d.ts +4 -0
- package/lib/typescript/src/skia/Picture/usePicture.d.ts +11 -0
- package/lib/typescript/src/skia/Skia.d.ts +5 -0
- package/lib/typescript/src/skia/index.d.ts +1 -0
- package/lib/typescript/src/views/SkiaView.d.ts +25 -1
- package/lib/typescript/src/views/types.d.ts +0 -24
- 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/Info.plist +5 -5
- 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 +1 -1
- package/src/renderer/Canvas.tsx +14 -30
- package/src/renderer/HostConfig.ts +1 -19
- package/src/renderer/components/Drawing.tsx +16 -0
- package/src/renderer/components/Group.tsx +1 -1
- package/src/renderer/components/Picture.tsx +17 -0
- package/src/renderer/components/imageFilters/InnerShadow.tsx +33 -47
- package/src/renderer/components/imageFilters/Shadow.tsx +39 -0
- package/src/renderer/components/imageFilters/index.ts +1 -2
- package/src/renderer/components/index.ts +2 -0
- package/src/renderer/components/maskFilters/Blur.tsx +1 -1
- package/src/renderer/components/shapes/Box.tsx +98 -0
- package/src/renderer/components/shapes/index.ts +1 -0
- package/src/renderer/index.ts +1 -0
- package/src/renderer/nodes/Declaration.tsx +10 -0
- package/src/renderer/nodes/Drawing.tsx +6 -6
- package/src/renderer/processors/math/Math.ts +16 -0
- package/src/renderer/processors/math/Matrix3.ts +35 -31
- package/src/renderer/typeddash.ts +18 -0
- package/src/renderer/useContextBridge.tsx +21 -0
- package/src/skia/Canvas.ts +7 -0
- package/src/skia/Picture/Picture.ts +34 -0
- package/src/skia/Picture/PictureFactory.ts +9 -0
- package/src/skia/Picture/PictureRecorder.ts +18 -0
- package/src/skia/Picture/index.ts +4 -0
- package/src/skia/Picture/usePicture.ts +28 -0
- package/src/skia/Skia.ts +5 -0
- package/src/skia/index.ts +1 -0
- package/src/values/hooks/useDerivedValue.ts +1 -1
- package/src/views/SkiaView.tsx +27 -3
- package/src/views/types.ts +0 -25
- package/lib/commonjs/renderer/components/imageFilters/DropShadow.js.map +0 -1
- package/lib/module/renderer/components/imageFilters/DropShadow.js.map +0 -1
- package/src/renderer/components/imageFilters/DropShadow.tsx +0 -31
package/src/renderer/Canvas.tsx
CHANGED
|
@@ -11,8 +11,6 @@ import type {
|
|
|
11
11
|
RefObject,
|
|
12
12
|
ReactNode,
|
|
13
13
|
ComponentProps,
|
|
14
|
-
Context,
|
|
15
|
-
ReactElement,
|
|
16
14
|
MutableRefObject,
|
|
17
15
|
ForwardedRef,
|
|
18
16
|
} from "react";
|
|
@@ -23,6 +21,8 @@ import { SkiaView, useDrawCallback } from "../views";
|
|
|
23
21
|
import type { TouchHandler } from "../views";
|
|
24
22
|
import { Skia } from "../skia";
|
|
25
23
|
import type { FontMgr } from "../skia/FontMgr/FontMgr";
|
|
24
|
+
import { useValue } from "../values/hooks/useValue";
|
|
25
|
+
import type { SkiaReadonlyValue } from "../values/types";
|
|
26
26
|
|
|
27
27
|
import { debug as hostDebug, skHostConfig } from "./HostConfig";
|
|
28
28
|
// import { debugTree } from "./nodes";
|
|
@@ -30,33 +30,12 @@ import { vec } from "./processors";
|
|
|
30
30
|
import { Container } from "./nodes";
|
|
31
31
|
import { DependencyManager } from "./DependencyManager";
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
-
export const useContextBridge = (...contexts: Context<any>[]) => {
|
|
36
|
-
const values =
|
|
37
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
38
|
-
contexts.map((context) => useContext(context));
|
|
39
|
-
return useMemo(
|
|
40
|
-
() =>
|
|
41
|
-
({ children }: { children: ReactNode }) =>
|
|
42
|
-
contexts.reduceRight(
|
|
43
|
-
(acc, Context, i) => (
|
|
44
|
-
<Context.Provider value={values[i]} children={acc} />
|
|
45
|
-
),
|
|
46
|
-
children
|
|
47
|
-
) as ReactElement,
|
|
48
|
-
[contexts, values]
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
interface CanvasContext {
|
|
33
|
+
const CanvasContext = React.createContext<SkiaReadonlyValue<{
|
|
53
34
|
width: number;
|
|
54
35
|
height: number;
|
|
55
|
-
}
|
|
36
|
+
}> | null>(null);
|
|
56
37
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
export const useCanvas = () => {
|
|
38
|
+
export const useCanvasSize = () => {
|
|
60
39
|
const canvas = useContext(CanvasContext);
|
|
61
40
|
if (!canvas) {
|
|
62
41
|
throw new Error("Canvas context is not available");
|
|
@@ -93,6 +72,7 @@ const defaultFontMgr = Skia.FontMgr.RefDefault();
|
|
|
93
72
|
|
|
94
73
|
export const Canvas = forwardRef<SkiaView, CanvasProps>(
|
|
95
74
|
({ children, style, debug, mode, onTouch, fontMgr }, forwardedRef) => {
|
|
75
|
+
const canvasCtx = useValue({ width: 0, height: 0 });
|
|
96
76
|
const innerRef = useCanvasRef();
|
|
97
77
|
const ref = useCombinedRefs(forwardedRef, innerRef);
|
|
98
78
|
const [tick, setTick] = useState(0);
|
|
@@ -103,7 +83,6 @@ export const Canvas = forwardRef<SkiaView, CanvasProps>(
|
|
|
103
83
|
[redraw, ref]
|
|
104
84
|
);
|
|
105
85
|
|
|
106
|
-
const canvasCtx = useRef({ width: 0, height: 0 });
|
|
107
86
|
const root = useMemo(
|
|
108
87
|
() => skiaReconciler.createContainer(container, 0, false, null),
|
|
109
88
|
[container]
|
|
@@ -111,13 +90,13 @@ export const Canvas = forwardRef<SkiaView, CanvasProps>(
|
|
|
111
90
|
// Render effect
|
|
112
91
|
useEffect(() => {
|
|
113
92
|
render(
|
|
114
|
-
<CanvasContext.Provider value={canvasCtx
|
|
93
|
+
<CanvasContext.Provider value={canvasCtx}>
|
|
115
94
|
{children}
|
|
116
95
|
</CanvasContext.Provider>,
|
|
117
96
|
root,
|
|
118
97
|
container
|
|
119
98
|
);
|
|
120
|
-
}, [children, root, redraw, container]);
|
|
99
|
+
}, [children, root, redraw, container, canvasCtx]);
|
|
121
100
|
|
|
122
101
|
// Draw callback
|
|
123
102
|
const onDraw = useDrawCallback(
|
|
@@ -127,6 +106,12 @@ export const Canvas = forwardRef<SkiaView, CanvasProps>(
|
|
|
127
106
|
if (onTouch) {
|
|
128
107
|
onTouch(info.touches);
|
|
129
108
|
}
|
|
109
|
+
if (
|
|
110
|
+
width !== canvasCtx.current.width ||
|
|
111
|
+
height !== canvasCtx.current.height
|
|
112
|
+
) {
|
|
113
|
+
canvasCtx.current = { width, height };
|
|
114
|
+
}
|
|
130
115
|
const paint = Skia.Paint();
|
|
131
116
|
paint.setAntiAlias(true);
|
|
132
117
|
const ctx = {
|
|
@@ -140,7 +125,6 @@ export const Canvas = forwardRef<SkiaView, CanvasProps>(
|
|
|
140
125
|
center: vec(width / 2, height / 2),
|
|
141
126
|
fontMgr: fontMgr ?? defaultFontMgr,
|
|
142
127
|
};
|
|
143
|
-
canvasCtx.current = ctx;
|
|
144
128
|
container.draw(ctx);
|
|
145
129
|
},
|
|
146
130
|
[tick, onTouch]
|
|
@@ -3,7 +3,7 @@ import type { HostConfig } from "react-reconciler";
|
|
|
3
3
|
|
|
4
4
|
import type { Node, Container, DeclarationProps, DrawingProps } from "./nodes";
|
|
5
5
|
import { DeclarationNode, DrawingNode, NodeType } from "./nodes";
|
|
6
|
-
import { exhaustiveCheck,
|
|
6
|
+
import { exhaustiveCheck, shallowEq } from "./typeddash";
|
|
7
7
|
|
|
8
8
|
const DEBUG = false;
|
|
9
9
|
export const debug = (...args: Parameters<typeof console.log>) => {
|
|
@@ -53,24 +53,6 @@ type SkiaHostConfig = HostConfig<
|
|
|
53
53
|
NoTimeout
|
|
54
54
|
>;
|
|
55
55
|
|
|
56
|
-
// Shallow eq on props (without children)
|
|
57
|
-
const shallowEq = <P extends Props>(p1: P, p2: P): boolean => {
|
|
58
|
-
const keys1 = mapKeys(p1);
|
|
59
|
-
const keys2 = mapKeys(p2);
|
|
60
|
-
if (keys1.length !== keys2.length) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
for (const key of keys1) {
|
|
64
|
-
if (key === "children") {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (p1[key] !== p2[key]) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return true;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
56
|
const allChildrenAreMemoized = (node: Instance) => {
|
|
75
57
|
if (!node.memoizable) {
|
|
76
58
|
return false;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import type { DrawingContext } from "../DrawingContext";
|
|
4
|
+
import { createDrawing } from "../nodes/Drawing";
|
|
5
|
+
|
|
6
|
+
interface DrawingProps {
|
|
7
|
+
drawing: (ctx: DrawingContext) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const onDraw = createDrawing<DrawingProps>((ctx, { drawing }) => {
|
|
11
|
+
drawing(ctx);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const Drawing = (props: DrawingProps) => {
|
|
15
|
+
return <skDrawing onDraw={onDraw} skipProcessing {...props} />;
|
|
16
|
+
};
|
|
@@ -33,7 +33,7 @@ const onDraw = createDrawing<GroupProps>(
|
|
|
33
33
|
processPaint(paint, opacity, groupProps);
|
|
34
34
|
const hasTransform = !!groupProps.transform || !!groupProps.matrix;
|
|
35
35
|
const hasClip = !!clip;
|
|
36
|
-
const shouldSave = hasTransform || hasClip;
|
|
36
|
+
const shouldSave = hasTransform || hasClip || !!layer;
|
|
37
37
|
if (shouldSave) {
|
|
38
38
|
if (layer) {
|
|
39
39
|
if (typeof layer === "boolean") {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import type { SkPicture } from "../../skia";
|
|
4
|
+
import { createDrawing } from "../nodes/Drawing";
|
|
5
|
+
|
|
6
|
+
export interface PictureProps {
|
|
7
|
+
picture: SkPicture;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const onDraw = createDrawing<PictureProps>((ctx, { picture }) => {
|
|
11
|
+
const { canvas } = ctx;
|
|
12
|
+
canvas.drawPicture(picture);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const Picture = (props: PictureProps) => {
|
|
16
|
+
return <skDrawing onDraw={onDraw} {...props} skipProcessing />;
|
|
17
|
+
};
|
|
@@ -1,50 +1,36 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { SkColor } from "../../../skia";
|
|
2
|
+
import { BlendMode, Skia, TileMode } from "../../../skia";
|
|
3
|
+
import type { SkImageFilter } from "../../../skia/ImageFilter/ImageFilter";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
null
|
|
30
|
-
);
|
|
31
|
-
const f1 = Skia.ImageFilter.MakeColorFilter(
|
|
32
|
-
Skia.ColorFilter.MakeBlend(cl, BlendMode.SrcOut),
|
|
33
|
-
null
|
|
34
|
-
);
|
|
35
|
-
const f2 = Skia.ImageFilter.MakeOffset(dx, dy, f1);
|
|
36
|
-
const f3 = Skia.ImageFilter.MakeBlur(blur, blur, TileMode.Decal, f2);
|
|
37
|
-
const f4 = Skia.ImageFilter.MakeBlend(BlendMode.SrcIn, sourceAlpha, f3);
|
|
38
|
-
if (shadowOnly) {
|
|
39
|
-
return f4;
|
|
40
|
-
}
|
|
41
|
-
return Skia.ImageFilter.MakeCompose(
|
|
42
|
-
input,
|
|
43
|
-
Skia.ImageFilter.MakeBlend(BlendMode.SrcOver, sourceGraphic, f4)
|
|
44
|
-
);
|
|
5
|
+
export const MakeInnerShadow = (
|
|
6
|
+
shadowOnly: boolean | undefined,
|
|
7
|
+
dx: number,
|
|
8
|
+
dy: number,
|
|
9
|
+
sigmaX: number,
|
|
10
|
+
sigmaY: number,
|
|
11
|
+
color: SkColor,
|
|
12
|
+
input: SkImageFilter | null
|
|
13
|
+
) => {
|
|
14
|
+
const sourceGraphic = Skia.ImageFilter.MakeColorFilter(
|
|
15
|
+
Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.Dst),
|
|
16
|
+
null
|
|
17
|
+
);
|
|
18
|
+
const sourceAlpha = Skia.ImageFilter.MakeColorFilter(
|
|
19
|
+
Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.SrcIn),
|
|
20
|
+
null
|
|
21
|
+
);
|
|
22
|
+
const f1 = Skia.ImageFilter.MakeColorFilter(
|
|
23
|
+
Skia.ColorFilter.MakeBlend(color, BlendMode.SrcOut),
|
|
24
|
+
null
|
|
25
|
+
);
|
|
26
|
+
const f2 = Skia.ImageFilter.MakeOffset(dx, dy, f1);
|
|
27
|
+
const f3 = Skia.ImageFilter.MakeBlur(sigmaX, sigmaY, TileMode.Decal, f2);
|
|
28
|
+
const f4 = Skia.ImageFilter.MakeBlend(BlendMode.SrcIn, sourceAlpha, f3);
|
|
29
|
+
if (shadowOnly) {
|
|
30
|
+
return f4;
|
|
45
31
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
32
|
+
return Skia.ImageFilter.MakeCompose(
|
|
33
|
+
input,
|
|
34
|
+
Skia.ImageFilter.MakeBlend(BlendMode.SrcOver, sourceGraphic, f4)
|
|
35
|
+
);
|
|
50
36
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { Skia } from "../../../skia";
|
|
4
|
+
import { createDeclaration } from "../../nodes/Declaration";
|
|
5
|
+
import type { AnimatedProps } from "../../processors/Animations/Animations";
|
|
6
|
+
import type { Color } from "../../../skia/Color";
|
|
7
|
+
import { processColor } from "../../../skia/Color";
|
|
8
|
+
|
|
9
|
+
import { getInput } from "./getInput";
|
|
10
|
+
import { MakeInnerShadow } from "./InnerShadow";
|
|
11
|
+
|
|
12
|
+
export interface ShadowProps {
|
|
13
|
+
dx: number;
|
|
14
|
+
dy: number;
|
|
15
|
+
blur: number;
|
|
16
|
+
color: Color;
|
|
17
|
+
inner?: boolean;
|
|
18
|
+
shadowOnly?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const onDeclare = createDeclaration<ShadowProps>(
|
|
22
|
+
({ dx, dy, blur, color: cl, shadowOnly, inner }, children, { opacity }) => {
|
|
23
|
+
const input = getInput(children);
|
|
24
|
+
const color = processColor(cl, opacity);
|
|
25
|
+
let factory;
|
|
26
|
+
if (inner) {
|
|
27
|
+
factory = MakeInnerShadow.bind(null, shadowOnly);
|
|
28
|
+
} else {
|
|
29
|
+
factory = shadowOnly
|
|
30
|
+
? Skia.ImageFilter.MakeDropShadowOnly
|
|
31
|
+
: Skia.ImageFilter.MakeDropShadow;
|
|
32
|
+
}
|
|
33
|
+
return factory(dx, dy, blur, blur, color, input);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const Shadow = (props: AnimatedProps<ShadowProps>) => {
|
|
38
|
+
return <skDeclaration onDeclare={onDeclare} {...props} />;
|
|
39
|
+
};
|
|
@@ -8,6 +8,7 @@ export * from "./maskFilters";
|
|
|
8
8
|
export * from "./imageFilters";
|
|
9
9
|
export * from "./pathEffects";
|
|
10
10
|
export * from "../processors";
|
|
11
|
+
export * from "./Picture";
|
|
11
12
|
|
|
12
13
|
export * from "./Group";
|
|
13
14
|
export * from "./Mask";
|
|
@@ -15,3 +16,4 @@ export * from "./Paint";
|
|
|
15
16
|
export * from "./Compose";
|
|
16
17
|
export * from "./Blend";
|
|
17
18
|
export * from "./Defs";
|
|
19
|
+
export * from "./Drawing";
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import type { Color, SkRRect } from "../../../skia";
|
|
4
|
+
import { ClipOp, BlurStyle, Skia, processColor } from "../../../skia";
|
|
5
|
+
import { createDrawing } from "../../nodes";
|
|
6
|
+
import type { AnimatedProps, CustomPaintProps } from "../../processors";
|
|
7
|
+
import { add, vec, rrect } from "../../processors";
|
|
8
|
+
import { rect, isRRect } from "../../processors/Rects";
|
|
9
|
+
import { createDeclaration } from "../../nodes/Declaration";
|
|
10
|
+
import type { SkJSIInstance } from "../../../skia/JsiInstance";
|
|
11
|
+
import type { SkRect } from "../../../skia/Rect";
|
|
12
|
+
|
|
13
|
+
const inflate = (box: SkRRect, dx: number, dy: number, tx = 0, ty = 0) =>
|
|
14
|
+
rrect(
|
|
15
|
+
rect(
|
|
16
|
+
box.rect.x - dx + tx,
|
|
17
|
+
box.rect.y - dy + ty,
|
|
18
|
+
box.rect.width + 2 * dx,
|
|
19
|
+
box.rect.height + 2 * dy
|
|
20
|
+
),
|
|
21
|
+
box.rx + dx,
|
|
22
|
+
box.ry + dy
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const deflate = (box: SkRRect, dx: number, dy: number, tx = 0, ty = 0) =>
|
|
26
|
+
inflate(box, -dx, -dy, tx, ty);
|
|
27
|
+
|
|
28
|
+
interface BoxShadowProps {
|
|
29
|
+
dx?: number;
|
|
30
|
+
dy?: number;
|
|
31
|
+
spread?: number;
|
|
32
|
+
blur: number;
|
|
33
|
+
color?: Color;
|
|
34
|
+
inner?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface BoxShadowDecl extends BoxShadowProps, SkJSIInstance<"BoxShadow"> {}
|
|
38
|
+
|
|
39
|
+
const onDeclare = createDeclaration<BoxShadowProps>(
|
|
40
|
+
({ dx, dy, spread, blur, color, inner }) => {
|
|
41
|
+
return { dx, dy, spread, blur, color, inner, __typename__: "BoxShadow" };
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export const BoxShadow = (props: AnimatedProps<BoxShadowProps>) => {
|
|
46
|
+
return <skDeclaration onDeclare={onDeclare} {...props} />;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const isBoxShadow = (s: SkJSIInstance<string>): s is BoxShadowDecl =>
|
|
50
|
+
s.__typename__ === "BoxShadow";
|
|
51
|
+
|
|
52
|
+
interface BoxProps extends CustomPaintProps {
|
|
53
|
+
box: SkRRect | SkRect;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const onDraw = createDrawing<BoxProps>((ctx, { box: defaultBox }, node) => {
|
|
57
|
+
const box = isRRect(defaultBox) ? defaultBox : rrect(defaultBox, 0, 0);
|
|
58
|
+
const { canvas, paint, opacity } = ctx;
|
|
59
|
+
const shadows = node.visit(ctx).filter<BoxShadowDecl>(isBoxShadow);
|
|
60
|
+
shadows
|
|
61
|
+
.filter((shadow) => !shadow.inner)
|
|
62
|
+
.map((shadow) => {
|
|
63
|
+
const { color = "black", blur, spread = 0, dx = 0, dy = 0 } = shadow;
|
|
64
|
+
const lPaint = Skia.Paint();
|
|
65
|
+
lPaint.setColor(processColor(color, opacity));
|
|
66
|
+
lPaint.setMaskFilter(
|
|
67
|
+
Skia.MaskFilter.MakeBlur(BlurStyle.Normal, blur, true)
|
|
68
|
+
);
|
|
69
|
+
canvas.drawRRect(inflate(box, spread, spread, dx, dy), lPaint);
|
|
70
|
+
});
|
|
71
|
+
canvas.drawRRect(box, paint);
|
|
72
|
+
|
|
73
|
+
shadows
|
|
74
|
+
.filter((shadow) => shadow.inner)
|
|
75
|
+
.map((shadow) => {
|
|
76
|
+
const { color = "black", blur, spread = 0, dx = 0, dy = 0 } = shadow;
|
|
77
|
+
const delta = add(vec(10, 10), vec(Math.abs(dx), Math.abs(dy)));
|
|
78
|
+
canvas.save();
|
|
79
|
+
canvas.clipRRect(box, ClipOp.Intersect, false);
|
|
80
|
+
const lPaint = Skia.Paint();
|
|
81
|
+
lPaint.setColor(processColor(color, opacity));
|
|
82
|
+
lPaint.setMaskFilter(
|
|
83
|
+
Skia.MaskFilter.MakeBlur(BlurStyle.Normal, blur, true)
|
|
84
|
+
);
|
|
85
|
+
const inner = deflate(box, spread, spread, dx, dy);
|
|
86
|
+
const outer = inflate(box, delta.x, delta.y);
|
|
87
|
+
canvas.drawDRRect(outer, inner, lPaint);
|
|
88
|
+
canvas.restore();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export const Box = (props: AnimatedProps<BoxProps>) => {
|
|
93
|
+
return <skDrawing onDraw={onDraw} {...props} />;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
Box.defaultProps = {
|
|
97
|
+
shadows: [],
|
|
98
|
+
};
|
package/src/renderer/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { DependencyList } from "react";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
|
|
1
4
|
import type { DrawingContext } from "../DrawingContext";
|
|
2
5
|
import type { SkJSIInstance } from "../../skia/JsiInstance";
|
|
3
6
|
import type { AnimatedProps } from "../processors";
|
|
@@ -18,6 +21,13 @@ export const createDeclaration = <T,>(
|
|
|
18
21
|
cb: DeclarationCallback<T>
|
|
19
22
|
): DeclarationCallback<T> => cb;
|
|
20
23
|
|
|
24
|
+
export const useDeclaration = <P,>(
|
|
25
|
+
cb: DeclarationCallback<P>,
|
|
26
|
+
deps?: DependencyList
|
|
27
|
+
) =>
|
|
28
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29
|
+
useCallback(cb, deps ?? []);
|
|
30
|
+
|
|
21
31
|
export interface DeclarationProps<P> {
|
|
22
32
|
onDeclare: DeclarationCallback<P>;
|
|
23
33
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
import
|
|
1
|
+
import type { DependencyList, ReactNode } from "react";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
3
|
|
|
4
4
|
import type { DrawingContext } from "../DrawingContext";
|
|
5
5
|
import { processPaint, selectPaint } from "../processors";
|
|
@@ -21,16 +21,16 @@ type OnDrawCallback<P> = (ctx: DrawingContext, props: P, node: Node<P>) => void;
|
|
|
21
21
|
export const createDrawing = <P,>(cb: OnDrawCallback<P>): DrawingCallback<P> =>
|
|
22
22
|
cb;
|
|
23
23
|
|
|
24
|
+
export const useDrawing = <P,>(cb: OnDrawCallback<P>, deps?: DependencyList) =>
|
|
25
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
|
+
useCallback(cb, deps ?? []);
|
|
27
|
+
|
|
24
28
|
export type DrawingProps<T> = {
|
|
25
29
|
onDraw: DrawingCallback<T>;
|
|
26
30
|
skipProcessing?: boolean;
|
|
27
31
|
children?: ReactNode | ReactNode[];
|
|
28
32
|
};
|
|
29
33
|
|
|
30
|
-
export const Drawing = <P,>(props: DrawingProps<P>) => {
|
|
31
|
-
return <skDrawing {...props} />;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
34
|
export class DrawingNode<P> extends Node<P> {
|
|
35
35
|
onDraw: DrawingCallback<P>;
|
|
36
36
|
skipProcessing: boolean;
|
|
@@ -1,2 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear interpolation
|
|
3
|
+
* @param value
|
|
4
|
+
* @param x
|
|
5
|
+
* @param y
|
|
6
|
+
*/
|
|
1
7
|
export const mix = (value: number, x: number, y: number) =>
|
|
2
8
|
x * (1 - value) + y * value;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @summary Clamps a node with a lower and upper bound.
|
|
12
|
+
* @example
|
|
13
|
+
clamp(-1, 0, 100); // 0
|
|
14
|
+
clamp(1, 0, 100); // 1
|
|
15
|
+
clamp(101, 0, 100); // 100
|
|
16
|
+
*/
|
|
17
|
+
export const clamp = (value: number, lowerBound: number, upperBound: number) =>
|
|
18
|
+
Math.min(Math.max(lowerBound, value), upperBound);
|
|
@@ -102,6 +102,9 @@ const multiply3 = (m1: Matrix3, m2: Matrix3) => {
|
|
|
102
102
|
] as const;
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
+
export const matrixVecMul3 = (m: Matrix3, v: Vec3) =>
|
|
106
|
+
[dot3(m[0], v), dot3(m[1], v), dot3(m[2], v)] as const;
|
|
107
|
+
|
|
105
108
|
const skiaMatrix3 = (m: Matrix3): SkMatrix => {
|
|
106
109
|
return [
|
|
107
110
|
m[0][0],
|
|
@@ -117,34 +120,35 @@ const skiaMatrix3 = (m: Matrix3): SkMatrix => {
|
|
|
117
120
|
};
|
|
118
121
|
|
|
119
122
|
export const processTransform2d = (transforms: Transforms2d) =>
|
|
120
|
-
skiaMatrix3(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
|
|
123
|
+
skiaMatrix3(processTransform(transforms));
|
|
124
|
+
|
|
125
|
+
const processTransform = (transforms: Transforms2d) =>
|
|
126
|
+
transforms.reduce((acc, transform) => {
|
|
127
|
+
const key = Object.keys(transform)[0] as Transform2dName;
|
|
128
|
+
const value = (transform as Pick<Transformations, typeof key>)[key];
|
|
129
|
+
if (key === "translateX") {
|
|
130
|
+
return multiply3(acc, translateXMatrix(value));
|
|
131
|
+
}
|
|
132
|
+
if (key === "translateY") {
|
|
133
|
+
return multiply3(acc, translateYMatrix(value));
|
|
134
|
+
}
|
|
135
|
+
if (key === "scale") {
|
|
136
|
+
return multiply3(acc, scaleMatrix(value));
|
|
137
|
+
}
|
|
138
|
+
if (key === "scaleX") {
|
|
139
|
+
return multiply3(acc, scaleXMatrix(value));
|
|
140
|
+
}
|
|
141
|
+
if (key === "scaleY") {
|
|
142
|
+
return multiply3(acc, scaleYMatrix(value));
|
|
143
|
+
}
|
|
144
|
+
if (key === "skewX") {
|
|
145
|
+
return multiply3(acc, skewXMatrix(value));
|
|
146
|
+
}
|
|
147
|
+
if (key === "skewY") {
|
|
148
|
+
return multiply3(acc, skewYMatrix(value));
|
|
149
|
+
}
|
|
150
|
+
if (key === "rotate" || key === "rotateZ") {
|
|
151
|
+
return multiply3(acc, rotateZMatrix(value));
|
|
152
|
+
}
|
|
153
|
+
return exhaustiveCheck(key);
|
|
154
|
+
}, identityMatrix);
|
|
@@ -3,3 +3,21 @@ export const mapKeys = <T>(obj: T) => Object.keys(obj) as (keyof T)[];
|
|
|
3
3
|
export const exhaustiveCheck = (a: never): never => {
|
|
4
4
|
throw new Error(`Unexhaustive handling for ${a}`);
|
|
5
5
|
};
|
|
6
|
+
|
|
7
|
+
// Shallow eq on props (without children)
|
|
8
|
+
export const shallowEq = <P>(p1: P, p2: P): boolean => {
|
|
9
|
+
const keys1 = mapKeys(p1);
|
|
10
|
+
const keys2 = mapKeys(p2);
|
|
11
|
+
if (keys1.length !== keys2.length) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
for (const key of keys1) {
|
|
15
|
+
if (key === "children") {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (p1[key] !== p2[key]) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { useMemo, useContext } from "react";
|
|
2
|
+
import type { ReactNode, Context, ReactElement } from "react";
|
|
3
|
+
|
|
4
|
+
// useContextBridge() is taken from https://github.com/pmndrs/drei#usecontextbridge
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
export const useContextBridge = (...contexts: Context<any>[]) => {
|
|
7
|
+
const values =
|
|
8
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
9
|
+
contexts.map((context) => useContext(context));
|
|
10
|
+
return useMemo(
|
|
11
|
+
() =>
|
|
12
|
+
({ children }: { children: ReactNode }) =>
|
|
13
|
+
contexts.reduceRight(
|
|
14
|
+
(acc, Context, i) => (
|
|
15
|
+
<Context.Provider value={values[i]} children={acc} />
|
|
16
|
+
),
|
|
17
|
+
children
|
|
18
|
+
) as ReactElement,
|
|
19
|
+
[contexts, values]
|
|
20
|
+
);
|
|
21
|
+
};
|
package/src/skia/Canvas.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { SkMatrix } from "./Matrix";
|
|
|
12
12
|
import type { SkImageFilter } from "./ImageFilter";
|
|
13
13
|
import type { SkVertices } from "./Vertices";
|
|
14
14
|
import type { SkTextBlob } from "./TextBlob";
|
|
15
|
+
import type { SkPicture } from "./Picture";
|
|
15
16
|
|
|
16
17
|
export enum ClipOp {
|
|
17
18
|
Difference,
|
|
@@ -485,4 +486,10 @@ export interface SkCanvas {
|
|
|
485
486
|
* @param m
|
|
486
487
|
*/
|
|
487
488
|
concat(m: SkMatrix): void;
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Draws the given picture using the current clip, current matrix, and the provided paint.
|
|
492
|
+
* @param skp
|
|
493
|
+
*/
|
|
494
|
+
drawPicture(skp: SkPicture): void;
|
|
488
495
|
}
|