"use client";
import React, { Suspense, useMemo } from "react";
import { Canvas } from "@react-three/fiber";
import { Environment, OrbitControls, useGLTF } from "@react-three/drei";
import { AlertCircle, Box, ExternalLink, Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
interface Model3DViewerProps {
modelUrl?: string | null;
previewImageUrl?: string | null;
}
class ViewerErrorBoundary extends React.Component<
{ children: React.ReactNode; fallback: React.ReactNode },
{ hasError: boolean }
> {
constructor(props: { children: React.ReactNode; fallback: React.ReactNode }) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidUpdate(prevProps: { children: React.ReactNode }) {
if (prevProps.children !== this.props.children && this.state.hasError) {
this.setState({ hasError: false });
}
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
function ModelScene({ url }: { url: string }) {
const model = useGLTF(url);
const scene = useMemo(() => model.scene.clone(), [model.scene]);
return
生成完成后可在此区域预览 3D 资产
当前文件格式不支持内嵌预览,请在新窗口打开
3D 预览加载失败,请尝试在新窗口打开
} >