| 393 | }; |
| 394 | |
| 395 | const ModelViewer: FC<ViewerProps> = ({ |
| 396 | url, |
| 397 | width = 400, |
| 398 | height = 400, |
| 399 | modelXOffset = 0, |
| 400 | modelYOffset = 0, |
| 401 | defaultRotationX = -50, |
| 402 | defaultRotationY = 20, |
| 403 | defaultZoom = 0.5, |
| 404 | minZoomDistance = 0.5, |
| 405 | maxZoomDistance = 10, |
| 406 | enableMouseParallax = true, |
| 407 | enableManualRotation = true, |
| 408 | enableHoverRotation = true, |
| 409 | enableManualZoom = true, |
| 410 | ambientIntensity = 0.3, |
| 411 | keyLightIntensity = 1, |
| 412 | fillLightIntensity = 0.5, |
| 413 | rimLightIntensity = 0.8, |
| 414 | environmentPreset = 'forest', |
| 415 | autoFrame = false, |
| 416 | placeholderSrc, |
| 417 | showScreenshotButton = true, |
| 418 | fadeIn = false, |
| 419 | autoRotate = false, |
| 420 | autoRotateSpeed = 0.35, |
| 421 | onModelLoaded |
| 422 | }) => { |
| 423 | useEffect(() => void useGLTF.preload(url), [url]); |
| 424 | const pivot = useRef(new THREE.Vector3()).current; |
| 425 | const contactRef = useRef<THREE.Mesh>(null); |
| 426 | const rendererRef = useRef<THREE.WebGLRenderer>(null); |
| 427 | const sceneRef = useRef<THREE.Scene>(null); |
| 428 | const cameraRef = useRef<THREE.Camera>(null); |
| 429 | |
| 430 | const initYaw = deg2rad(defaultRotationX); |
| 431 | const initPitch = deg2rad(defaultRotationY); |
| 432 | const camZ = Math.min(Math.max(defaultZoom, minZoomDistance), maxZoomDistance); |
| 433 | |
| 434 | const capture = () => { |
| 435 | const g = rendererRef.current, |
| 436 | s = sceneRef.current, |
| 437 | c = cameraRef.current; |
| 438 | if (!g || !s || !c) return; |
| 439 | g.shadowMap.enabled = false; |
| 440 | const tmp: { l: THREE.Light; cast: boolean }[] = []; |
| 441 | s.traverse((o: THREE.Object3D) => { |
| 442 | if (isLightObject(o)) { |
| 443 | tmp.push({ l: o, cast: o.castShadow }); |
| 444 | o.castShadow = false; |
| 445 | } |
| 446 | }); |
| 447 | if (contactRef.current) contactRef.current.visible = false; |
| 448 | g.render(s, c); |
| 449 | const urlPNG = g.domElement.toDataURL('image/png'); |
| 450 | const a = document.createElement('a'); |
| 451 | a.download = 'model.png'; |
| 452 | a.href = urlPNG; |