Skip to content

Commit

Permalink
Deprecate usePaintRef() (#1004)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon authored Oct 20, 2022
1 parent cd6ae25 commit e84fb1b
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 65 deletions.
23 changes: 12 additions & 11 deletions docs/docs/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,21 +240,22 @@ You can use it to apply effects.
This is particularly useful to build effects that need to be applied to a group of elements and not one in particular.

```tsx twoslash
import {Canvas, Group, Circle, Blur, Paint, ColorMatrix, usePaintRef} from "@shopify/react-native-skia";
import {Canvas, Group, Circle, Blur, Paint, ColorMatrix} from "@shopify/react-native-skia";

const Clip = () => {
const paint = usePaintRef();
return (
<Canvas style={{ flex: 1 }}>
<Paint ref={paint}>
<Blur blur={20} />
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
</Paint>
<Group color="lightblue" layer={paint}>
<Group
color="lightblue"
layer={<Paint>
<Blur blur={20} />
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
</Paint>}
>
<Circle cx={0} cy={128} r={128 * 0.95} />
<Circle
cx={256}
Expand Down
13 changes: 5 additions & 8 deletions docs/docs/paint/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,23 +127,20 @@ export const PaintDemo = () => {
Finally, we can assign a ref to a Paint component for later use.

```tsx twoslash
import {Canvas, Circle, Paint, usePaintRef} from "@shopify/react-native-skia";

import {Canvas, Circle, Paint, Skia} from "@shopify/react-native-skia";
const width = 256;
const height = 256;
const r = width / 2;
const paint = Skia.Paint();
paint.setColor(Skia.Color("lightblue"));

export const PaintDemo = () => {
const paint = usePaintRef();
return (
<Canvas style={{ flex: 1 }}>
<Paint ref={paint} color="lightblue" />
{/* We can assign the ref to any shape. This will be handy in advanced use-case */}
<Circle paint={paint} cx={r} cy={r} r={r} />
<Circle paint={paint} cx={r} cy={r} r={r} />
</Canvas>
);
};
```

<img src={require("/static/img/paint/assignement.png").default} width="256" height="256" />

<img src={require("/static/img/paint/assignement.png").default} width="256" height="256" />
23 changes: 12 additions & 11 deletions example/src/Examples/Gooey/Gooey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
rotate,
mixVector,
Paint,
usePaintRef,
Circle,
Blur,
ColorMatrix,
Expand Down Expand Up @@ -66,7 +65,6 @@ export const Gooey = () => {
[c]
);

const paint = usePaintRef();
const [toggled, setToggled] = useState(false);
const onTouch = useTouchHandler({ onEnd: () => setToggled((t) => !t) });
const progress = useSpring(toggled ? 1 : 0, Spring.Config.Gentle);
Expand All @@ -84,16 +82,19 @@ export const Gooey = () => {

return (
<Canvas style={{ flex: 1 }} onTouch={onTouch}>
<Paint ref={paint}>
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
<Blur blur={20} />
</Paint>
<Fill color={BG} />
<Group layer={paint}>
<Group
layer={
<Paint>
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
<Blur blur={20} />
</Paint>
}
>
{icons.map((_, i) => (
<Group key={i} transform={transforms[i]}>
<Circle r={R} color={FG} />
Expand Down
23 changes: 12 additions & 11 deletions example/src/Examples/Severance/CRT.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Group,
Skia,
RuntimeShader,
usePaintRef,
Paint,
vec,
} from "@shopify/react-native-skia";
Expand Down Expand Up @@ -58,17 +57,19 @@ interface CRTProps {
}

export const CRT = ({ children }: CRTProps) => {
const paint = usePaintRef();
const { width, height } = useWindowDimensions();
return (
<>
<Paint ref={paint}>
<RuntimeShader
source={source}
uniforms={{ resolution: vec(width, height) }}
/>
</Paint>
<Group layer={paint}>{children}</Group>
</>
<Group
layer={
<Paint>
<RuntimeShader
source={source}
uniforms={{ resolution: vec(width, height) }}
/>
</Paint>
}
>
{children}
</Group>
);
};
5 changes: 5 additions & 0 deletions package/src/dom/nodes/JsiSkDOM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,15 @@ import { MorphologyImageFilterNode } from "./paint/ImageFilters";
import { GroupNode } from "./GroupNode";
import { PaintNode } from "./PaintNode";
import type { NodeContext } from "./Node";
import { LayerNode } from "./LayerNode";

export class JsiSkDOM implements SkDOM {
constructor(private ctx: NodeContext) {}

Layer(props?: ChildrenProps) {
return new LayerNode(this.ctx, props ?? {});
}

Group(props?: GroupProps) {
return new GroupNode(this.ctx, props ?? {});
}
Expand Down
35 changes: 35 additions & 0 deletions package/src/dom/nodes/LayerNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { DeclarationNode, DrawingContext, Node } from "../types";
import { NodeType } from "../types";
import type { ChildrenProps } from "../types/Common";
import type { SkPaint } from "../../skia";

import { JsiRenderNode } from "./RenderNode";
import type { NodeContext } from "./Node";
import { JsiDeclarationNode } from "./Node";

const isLayer = (
node: Node<unknown>
): node is DeclarationNode<unknown, SkPaint> =>
node instanceof JsiDeclarationNode && node.isPaint();

export class LayerNode extends JsiRenderNode<ChildrenProps> {
constructor(ctx: NodeContext, props: ChildrenProps) {
super(ctx, NodeType.Layer, props);
}

renderNode(ctx: DrawingContext): void {
const [layer, ...children] = this.children();
if (isLayer(layer)) {
const paint = layer.materialize() as SkPaint;
ctx.canvas.saveLayer(paint);
}
children.map((child) => {
if (child instanceof JsiRenderNode) {
child.render(ctx);
}
});
if (isLayer(layer)) {
ctx.canvas.restore();
}
}
}
1 change: 1 addition & 0 deletions package/src/dom/types/NodeType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const enum NodeType {
// Shaders
Layer = "skLayer",
Shader = "skShader",
ImageShader = "skImageShader",
ColorShader = "skColorShader",
Expand Down
1 change: 1 addition & 0 deletions package/src/dom/types/SkDOM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type NullablePathEffectNode<P> = DeclarationNode<P, SkPathEffect, null>;
type DrawingNode<P extends GroupProps> = RenderNode<P>;

export interface SkDOM {
Layer(props?: ChildrenProps): RenderNode<ChildrenProps>;
Group(props?: GroupProps): RenderNode<GroupProps>;
Paint(props: PaintProps): DeclarationNode<PaintProps, SkPaint>;

Expand Down
3 changes: 3 additions & 0 deletions package/src/renderer/HostComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ declare global {
namespace JSX {
interface IntrinsicElements {
skGroup: SkiaProps<GroupProps>;
skLayer: SkiaProps<ChildrenProps>;
skPaint: SkiaProps<PaintProps> & { ref: ForwardedRef<PaintNode> };

// Drawings
Expand Down Expand Up @@ -146,6 +147,8 @@ export const createNode = (
) => {
const { Sk } = container;
switch (type) {
case NodeType.Layer:
return Sk.Layer(props);
case NodeType.Group:
return Sk.Group(props);
case NodeType.Paint:
Expand Down
24 changes: 13 additions & 11 deletions package/src/renderer/__tests__/documentation/Group.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,23 @@ const padding = 48;
const r = 24;

const TestRasterization = () => {
const { usePaintRef, vec } = importSkia();
const paint = usePaintRef();
const { vec } = importSkia();
const c = vec(width / 2, height / 2);
const radius = c.x * 0.95;
return (
<>
<Paint ref={paint}>
<Blur blur={20 * PIXEL_RATIO} />
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
</Paint>
<Group layer={paint}>
<Group
layer={
<Paint>
<Blur blur={20 * PIXEL_RATIO} />
<ColorMatrix
matrix={[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,
]}
/>
</Paint>
}
>
<Circle cx={0} cy={c.y} r={radius} color="lightblue" />
<Circle cx={width} cy={c.y} r={radius} color="lightblue" />
</Group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,11 @@ import { Circle, Group, Paint } from "../../../components";
import { docPath, processResult } from "../../../../__tests__/setup";

const TestPaintAssignment = () => {
const { usePaintRef } = importSkia();
const { Skia } = importSkia();
const paint = Skia.Paint();
paint.setColor(Skia.Color("lightblue"));
const r = width / 2;
const paint = usePaintRef();
return (
<>
<Paint ref={paint} color="lightblue" />
{/* We can assign the ref to any shape. This will be handy in advanced use-case */}
<Circle paint={paint} cx={r} cy={r} r={r} />
</>
);
return <Circle paint={paint} cx={r} cy={r} r={r} />;
};

describe("Paint", () => {
Expand Down
19 changes: 16 additions & 3 deletions package/src/renderer/components/Group.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import React from "react";
import React, { isValidElement } from "react";

import type { SkiaProps } from "../processors";
import type { GroupProps } from "../../dom/types";
import type { ChildrenProps } from "../../dom/types/Common";

export const Group = (props: SkiaProps<GroupProps>) => {
return <skGroup {...props} />;
export interface PublicGroupProps extends Omit<GroupProps, "layer"> {
layer?: GroupProps["layer"] | ChildrenProps["children"];
}

export const Group = ({ layer, ...props }: SkiaProps<PublicGroupProps>) => {
if (isValidElement(layer) && typeof layer === "object") {
return (
<skLayer>
{layer}
<skGroup {...props} />
</skLayer>
);
}
return <skGroup layer={layer as GroupProps["layer"]} {...props} />;
};
8 changes: 7 additions & 1 deletion package/src/renderer/components/Paint.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
/* eslint-disable max-len */
import React, { useRef, forwardRef } from "react";

import type { SkiaProps } from "../processors";
import type { DrawingNodeProps } from "../../dom/types";
import type { PaintNode } from "../../dom/nodes/PaintNode";

export const usePaintRef = () => useRef<PaintNode>(null);
export const usePaintRef = () => {
console.log(`usePaintRef() is now deprecated.
If you are using the layer property, simply pass the component directly: https://shopify.github.io/react-native-skia/docs/group#layer-effects.
If you are using the paint property, please the following paint properties directly: https://shopify.github.io/react-native-skia/docs/paint/overview`);
return useRef<PaintNode>(null);
};

export const Paint = forwardRef<PaintNode, SkiaProps<DrawingNodeProps>>(
(props, ref) => {
Expand Down

0 comments on commit e84fb1b

Please sign in to comment.