Changes
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user