This commit is contained in:
gpt-engineer-app[bot]
2026-02-27 00:41:06 +00:00
parent dc6b44fef9
commit 1cc84fb1f1
10 changed files with 3183 additions and 112 deletions
+79
View File
@@ -0,0 +1,79 @@
import { Suspense, useRef, useMemo } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls, useGLTF, Grid, Environment, Html } from '@react-three/drei';
import { Loader2 } from 'lucide-react';
import * as THREE from 'three';
interface ModelViewerProps {
url: string;
}
function LoadingFallback() {
return (
<Html center>
<div className="flex items-center gap-2 rounded-lg bg-card px-4 py-2 text-foreground shadow-lg">
<Loader2 className="h-4 w-4 animate-spin text-primary" />
<span className="font-mono text-sm">Carregando modelo</span>
</div>
</Html>
);
}
function GLBModel({ url }: { url: string }) {
const { scene } = useGLTF(url);
const ref = useRef<THREE.Group>(null);
const modelInfo = useMemo(() => {
const box = new THREE.Box3().setFromObject(scene);
const size = new THREE.Vector3();
const center = new THREE.Vector3();
box.getSize(size);
box.getCenter(center);
return { size, center };
}, [scene]);
return (
<group ref={ref} position={[-modelInfo.center.x, -modelInfo.center.y, -modelInfo.center.z]}>
<primitive object={scene} />
</group>
);
}
export function ModelViewerCanvas({ url }: ModelViewerProps) {
return (
<Canvas
camera={{ position: [2, 2, 2], fov: 50, near: 0.001, far: 1000 }}
gl={{ antialias: true, alpha: true }}
className="!bg-background"
>
<ambientLight intensity={0.6} />
<directionalLight position={[5, 10, 5]} intensity={1} castShadow />
<directionalLight position={[-5, 5, -5]} intensity={0.3} />
<Suspense fallback={<LoadingFallback />}>
<GLBModel url={url} />
</Suspense>
<Grid
infiniteGrid
cellSize={0.01}
sectionSize={0.1}
cellThickness={0.5}
sectionThickness={1}
cellColor="#334155"
sectionColor="#475569"
fadeDistance={5}
fadeStrength={1}
/>
<OrbitControls
makeDefault
enableDamping
dampingFactor={0.1}
minDistance={0.05}
maxDistance={50}
/>
</Canvas>
);
}