Skip to content

Commit 7174840

Browse files
committed
Add support for forwardRef
1 parent 2107b95 commit 7174840

1 file changed

Lines changed: 69 additions & 65 deletions

File tree

src/Canvas.tsx

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { FiberRoot } from 'react-reconciler';
1010
import { PaperScope } from 'paper/dist/paper-core';
1111
import { Renderer } from './Renderer';
1212

13-
type PaperScopeSettings = {
13+
export type PaperScopeSettings = {
1414
insertItems?: boolean;
1515
applyMatrix?: boolean;
1616
handleSize?: number;
@@ -24,74 +24,78 @@ export type Props = React.ComponentProps<'canvas'> & {
2424
onScopeReady?: (scope: paper.PaperScope) => void;
2525
};
2626

27-
export const Canvas = forwardRef<HTMLCanvasElement | null, Props>(
28-
({ children, width, height, settings, onScopeReady, ...other }, forwardedRef) => {
29-
const [canvas, setCanvas] = useState<HTMLCanvasElement | null>(null);
30-
const canvasRef = useRef<HTMLCanvasElement | null>(null);
31-
const scopeRef = useRef<paper.PaperScope | null>(null);
32-
const fiberRef = useRef<FiberRoot | null>(null);
33-
useImperativeHandle<HTMLCanvasElement | null, HTMLCanvasElement | null>(
34-
forwardedRef,
35-
() => canvasRef.current
36-
);
27+
export type CanvasRef = HTMLCanvasElement | null;
28+
export type ScopeRef = paper.PaperScope | null;
29+
export type FiberRef = FiberRoot | null;
3730

38-
// create
39-
useEffect(() => {
40-
if (canvas instanceof HTMLCanvasElement) {
41-
if (!scopeRef.current) {
42-
scopeRef.current = new PaperScope();
43-
}
44-
Object.assign(scopeRef.current.settings, {
45-
...settings,
46-
insertItems: false,
47-
});
48-
scopeRef.current.setup(canvas);
49-
fiberRef.current = Renderer.createContainer(
50-
scopeRef.current,
51-
ConcurrentRoot,
52-
null,
53-
false,
54-
null,
55-
'',
56-
console.error,
57-
null
58-
);
59-
Renderer.updateContainer(null, fiberRef.current, null, () => null);
60-
if (typeof onScopeReady === 'function') {
61-
onScopeReady(scopeRef.current);
62-
}
63-
} else if (canvasRef.current) {
64-
setCanvas(canvasRef.current);
65-
}
31+
export const Canvas = forwardRef<CanvasRef, Props>(function Canvas(
32+
props,
33+
forwardedRef
34+
) {
35+
const { children, width, height, settings, onScopeReady, ...other } = props;
36+
const [canvas, setCanvas] = useState<CanvasRef>(null);
37+
const canvasRef = useRef<CanvasRef>(null);
38+
const scopeRef = useRef<ScopeRef>(null);
39+
const fiberRef = useRef<FiberRef>(null);
6640

67-
// destroy
68-
return () => {
69-
if (canvas) {
70-
if (fiberRef.current) {
71-
Renderer.updateContainer(null, fiberRef.current, null, () => null);
72-
}
73-
scopeRef.current = null;
74-
canvasRef.current = null;
75-
fiberRef.current = null;
76-
}
77-
};
78-
// eslint-disable-next-line react-hooks/exhaustive-deps
79-
}, [canvas]);
41+
useImperativeHandle<CanvasRef, CanvasRef>(forwardedRef, () => canvasRef.current);
8042

81-
// update
82-
useEffect(() => {
83-
if (fiberRef.current) {
84-
Renderer.updateContainer(children, fiberRef.current, null, () => null);
43+
// create
44+
useEffect(() => {
45+
if (canvas instanceof HTMLCanvasElement) {
46+
if (!scopeRef.current) {
47+
scopeRef.current = new PaperScope();
8548
}
86-
}, [canvas, children]);
49+
Object.assign(scopeRef.current.settings, {
50+
...settings,
51+
insertItems: false,
52+
});
53+
scopeRef.current.setup(canvas);
54+
fiberRef.current = Renderer.createContainer(
55+
scopeRef.current,
56+
ConcurrentRoot,
57+
null,
58+
false,
59+
null,
60+
'',
61+
console.error,
62+
null
63+
);
64+
Renderer.updateContainer(null, fiberRef.current, null, () => null);
65+
if (typeof onScopeReady === 'function') {
66+
onScopeReady(scopeRef.current);
67+
}
68+
} else if (canvasRef.current) {
69+
setCanvas(canvasRef.current);
70+
}
8771

88-
// resize
89-
useEffect(() => {
90-
if (scopeRef.current) {
91-
scopeRef.current.view.viewSize = new scopeRef.current.Size(width, height);
72+
// destroy
73+
return () => {
74+
if (canvas) {
75+
if (fiberRef.current) {
76+
Renderer.updateContainer(null, fiberRef.current, null, () => null);
77+
}
78+
scopeRef.current = null;
79+
canvasRef.current = null;
80+
fiberRef.current = null;
9281
}
93-
}, [canvas, width, height]);
82+
};
83+
// eslint-disable-next-line react-hooks/exhaustive-deps
84+
}, [canvas]);
85+
86+
// update
87+
useEffect(() => {
88+
if (fiberRef.current) {
89+
Renderer.updateContainer(children, fiberRef.current, null, () => null);
90+
}
91+
}, [canvas, children]);
92+
93+
// resize
94+
useEffect(() => {
95+
if (scopeRef.current) {
96+
scopeRef.current.view.viewSize = new scopeRef.current.Size(width, height);
97+
}
98+
}, [canvas, width, height]);
9499

95-
return <canvas {...other} ref={canvasRef} />;
96-
}
97-
);
100+
return <canvas {...other} ref={canvasRef} />;
101+
});

0 commit comments

Comments
 (0)