1
0

vrm-demo.tsx 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { useContext, useCallback, useEffect, useState } from "react";
  2. import { ViewerContext } from "@/features/vrmViewer/viewerContext";
  3. export default function VRMDemo({
  4. vrmUrl,
  5. onLoaded,
  6. onError,
  7. }: {
  8. vrmUrl: string,
  9. onLoaded?: () => void,
  10. onError?: () => void,
  11. }) {
  12. const { viewer } = useContext(ViewerContext);
  13. const [isLoading, setIsLoading] = useState(true);
  14. const [loadingError, setLoadingError] = useState(false);
  15. useEffect(() => {
  16. setIsLoading(true);
  17. setLoadingError(false);
  18. }, [vrmUrl]);
  19. const canvasRef = useCallback(
  20. (canvas: HTMLCanvasElement) => {
  21. if (canvas) {
  22. viewer.setup(canvas);
  23. (new Promise(async (resolve, reject) => {
  24. try {
  25. const loaded = await viewer.loadVrm(vrmUrl);
  26. resolve(true);
  27. } catch (e) {
  28. reject();
  29. }
  30. }))
  31. .then(() => {
  32. console.log("vrm loaded");
  33. setIsLoading(false);
  34. setLoadingError(false);
  35. onLoaded && onLoaded();
  36. })
  37. .catch((e) => {
  38. console.error("vrm loading error", e);
  39. setLoadingError(true);
  40. setIsLoading(false);
  41. onError && onError();
  42. });
  43. }
  44. },
  45. [viewer, vrmUrl]
  46. );
  47. return (
  48. <>
  49. <canvas ref={canvasRef} className={"h-full w-full"} />
  50. {isLoading && (
  51. <p className="absolute text-gray-800 font-orbitron text-2xl">Loading...</p>
  52. )}
  53. {loadingError && (
  54. <p className="absolute text-gray-800 font-orbitron text-2xl">Error loading VRM model</p>
  55. )}
  56. </>
  57. );
  58. }