Function
ModelViewer
({
url,
width = 400,
height = 400,
modelXOffset = 0,
modelYOffset = 0,
defaultRotationX = -50,
defaultRotationY = 20,
defaultZoom = 0.5,
minZoomDistance = 0.5,
maxZoomDistance = 10,
enableMouseParallax = true,
enableManualRotation = true,
enableHoverRotation = true,
enableManualZoom = true,
ambientIntensity = 0.3,
keyLightIntensity = 1,
fillLightIntensity = 0.5,
rimLightIntensity = 0.8,
environmentPreset = 'forest',
autoFrame = false,
placeholderSrc,
showScreenshotButton = true,
fadeIn = false,
autoRotate = false,
autoRotateSpeed = 0.35,
onModelLoaded
})
Source from the content-addressed store, hash-verified
| 326 | }; |
| 327 | |
| 328 | const ModelViewer = ({ |
| 329 | url, |
| 330 | width = 400, |
| 331 | height = 400, |
| 332 | modelXOffset = 0, |
| 333 | modelYOffset = 0, |
| 334 | defaultRotationX = -50, |
| 335 | defaultRotationY = 20, |
| 336 | defaultZoom = 0.5, |
| 337 | minZoomDistance = 0.5, |
| 338 | maxZoomDistance = 10, |
| 339 | enableMouseParallax = true, |
| 340 | enableManualRotation = true, |
| 341 | enableHoverRotation = true, |
| 342 | enableManualZoom = true, |
| 343 | ambientIntensity = 0.3, |
| 344 | keyLightIntensity = 1, |
| 345 | fillLightIntensity = 0.5, |
| 346 | rimLightIntensity = 0.8, |
| 347 | environmentPreset = 'forest', |
| 348 | autoFrame = false, |
| 349 | placeholderSrc, |
| 350 | showScreenshotButton = true, |
| 351 | fadeIn = false, |
| 352 | autoRotate = false, |
| 353 | autoRotateSpeed = 0.35, |
| 354 | onModelLoaded |
| 355 | }) => { |
| 356 | useEffect(() => void useGLTF.preload(url), [url]); |
| 357 | const pivot = useRef(new THREE.Vector3()).current; |
| 358 | const contactRef = useRef(null); |
| 359 | const rendererRef = useRef(null); |
| 360 | const sceneRef = useRef(null); |
| 361 | const cameraRef = useRef(null); |
| 362 | |
| 363 | const initYaw = deg2rad(defaultRotationX); |
| 364 | const initPitch = deg2rad(defaultRotationY); |
| 365 | const camZ = Math.min(Math.max(defaultZoom, minZoomDistance), maxZoomDistance); |
| 366 | |
| 367 | const capture = () => { |
| 368 | const g = rendererRef.current, |
| 369 | s = sceneRef.current, |
| 370 | c = cameraRef.current; |
| 371 | if (!g || !s || !c) return; |
| 372 | g.shadowMap.enabled = false; |
| 373 | const tmp = []; |
| 374 | s.traverse(o => { |
| 375 | if (o.isLight && 'castShadow' in o) { |
| 376 | tmp.push({ l: o, cast: o.castShadow }); |
| 377 | o.castShadow = false; |
| 378 | } |
| 379 | }); |
| 380 | if (contactRef.current) contactRef.current.visible = false; |
| 381 | g.render(s, c); |
| 382 | const urlPNG = g.domElement.toDataURL('image/png'); |
| 383 | const a = document.createElement('a'); |
| 384 | a.download = 'model.png'; |
| 385 | a.href = urlPNG; |
Callers
nothing calls this directly
Tested by
no test coverage detected