Skip to content

Commit 20fd94e

Browse files
committed
update vite project
1 parent 066c701 commit 20fd94e

File tree

4 files changed

+128
-75
lines changed

4 files changed

+128
-75
lines changed

demos/vite-demo/src/components/SmelterCanvas.tsx

Lines changed: 0 additions & 71 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
2+
import type Smelter from '@swmansion/smelter-web-wasm';
3+
4+
type CanvasProps = React.DetailedHTMLProps<
5+
React.CanvasHTMLAttributes<HTMLCanvasElement>,
6+
HTMLCanvasElement
7+
>;
8+
9+
type SmelterCanvasProps = {
10+
smelter: Smelter;
11+
audio?: boolean;
12+
children: React.ReactElement;
13+
} & CanvasProps;
14+
15+
type UpdatedProps = {
16+
smelter: Smelter;
17+
width?: number | string;
18+
height?: number | string;
19+
audio?: boolean;
20+
};
21+
22+
type RegisterOptions = UpdatedProps & {
23+
outputId: string;
24+
canvas: HTMLCanvasElement;
25+
};
26+
27+
const getNewOutputId = (() => {
28+
let counter = 1;
29+
return () => {
30+
const outputId = `output-${counter}`;
31+
counter += 1;
32+
return outputId;
33+
};
34+
})();
35+
36+
export default function SmelterCanvasOutput(props: SmelterCanvasProps) {
37+
const { children, smelter, audio, ...canvasProps } = props;
38+
const [updatedProps, setUpdatedProps] = useState<UpdatedProps | undefined>();
39+
const [registerOptions, setRegisterOptions] = useState<RegisterOptions | undefined>(undefined);
40+
const key = useRef<number>(1);
41+
42+
const canvasRef = useCallback(
43+
async (updatedCanvas: HTMLCanvasElement | null) => {
44+
if (!updatedCanvas || !updatedProps || updatedCanvas === registerOptions?.canvas) {
45+
return;
46+
}
47+
const outputId = getNewOutputId();
48+
setRegisterOptions({
49+
...updatedProps,
50+
outputId,
51+
canvas: updatedCanvas,
52+
});
53+
},
54+
[updatedProps, registerOptions]
55+
);
56+
57+
useEffect(() => {
58+
// force new canvas
59+
key.current += 1;
60+
61+
setUpdatedProps({
62+
smelter,
63+
width: canvasProps.width,
64+
height: canvasProps.height,
65+
audio,
66+
});
67+
}, [canvasProps.width, canvasProps.height, smelter, audio]);
68+
69+
useEffect(() => {
70+
if (!registerOptions) {
71+
return;
72+
}
73+
const { audio, outputId, width, height, canvas } = registerOptions;
74+
const promise = smelter.registerOutput(outputId, children, {
75+
type: 'canvas',
76+
video: {
77+
canvas,
78+
resolution: {
79+
width: Number(width ?? canvas?.width),
80+
height: Number(height ?? canvas?.height),
81+
},
82+
},
83+
audio,
84+
});
85+
86+
return () => {
87+
void promise
88+
.catch(console.error)
89+
.then(() => smelter.unregisterOutput(outputId))
90+
.catch(console.error);
91+
};
92+
}, [registerOptions]);
93+
94+
return <canvas key={key.current} ref={canvasRef} {...canvasProps} />;
95+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Smelter from '@swmansion/smelter-web-wasm';
2+
import { useEffect, useState } from 'react';
3+
4+
export function useSmelter(): Smelter | undefined {
5+
const [smelter, setSmelter] = useState<Smelter>();
6+
useEffect(() => {
7+
const smelter = new Smelter();
8+
9+
let cancel = false;
10+
const promise = (async () => {
11+
await smelter.init();
12+
await smelter.start();
13+
if (!cancel) {
14+
setSmelter(smelter);
15+
}
16+
})();
17+
18+
return () => {
19+
cancel = true;
20+
void (async () => {
21+
await promise.catch(() => {});
22+
await smelter.terminate();
23+
})();
24+
};
25+
}, []);
26+
return smelter;
27+
}

demos/vite-demo/src/pages/CanvasPage.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { View, Text, useInputStreams, InputStream, Tiles } from '@swmansion/smelter';
22
import Smelter, { setWasmBundleUrl } from '@swmansion/smelter-web-wasm';
33
import { useCallback, useState } from 'react';
4-
import SmelterCanvas from '../components/SmelterCanvas';
4+
import SmelterCanvas from '../components/SmelterCanvasOutput';
5+
import { useSmelter } from '../hooks/useSmelter';
6+
import SmelterCanvasOutput from '../components/SmelterCanvasOutput';
57

68
setWasmBundleUrl('/assets/smelter.wasm');
79

810
const CAMERA_ID = 'camera';
911
const SCREEN_SHARE_ID = 'screen';
1012

1113
export default function CanvasPage() {
12-
const [smelter, setSmelter] = useState<Smelter>();
14+
const smelter = useSmelter();
1315
const [camera, setCamera] = useState<boolean>();
1416
const [screen, setScreen] = useState<boolean>();
1517

@@ -63,9 +65,9 @@ export default function CanvasPage() {
6365
<p className="">Canvas: </p>
6466
</div>
6567
<div>
66-
<SmelterCanvas width={1280} height={720} onSmelterCreated={setSmelter}>
68+
{smelter && <SmelterCanvasOutput smelter={smelter} width={1280} height={720} audio>
6769
<SmelterComponent />
68-
</SmelterCanvas>
70+
</SmelterCanvasOutput>}
6971
</div>
7072
</div>
7173
);

0 commit comments

Comments
 (0)