Spaces:
Sleeping
Sleeping
| import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react' | |
| import { useThree, useLoader } from '@react-three/fiber' | |
| import * as THREE from 'three' | |
| export interface EnvironmentMapHandle { | |
| setIntensity: (amount: number) => void | |
| } | |
| interface Props { | |
| panoUrl: string | |
| intensity: number | |
| } | |
| const BACKGROUND_BLURRINESS = 1 | |
| export const EnvironmentMap = forwardRef<EnvironmentMapHandle, Props>( | |
| function EnvironmentMap({ panoUrl, intensity }, ref) { | |
| const texture = useLoader(THREE.TextureLoader, panoUrl) | |
| const { scene } = useThree() | |
| const transitionAmountRef = useRef(1) | |
| const applyIntensity = useCallback(() => { | |
| const v = transitionAmountRef.current * intensity | |
| scene.environmentIntensity = v | |
| scene.backgroundIntensity = v | |
| }, [intensity, scene]) | |
| useEffect(() => { | |
| texture.mapping = THREE.EquirectangularReflectionMapping | |
| texture.colorSpace = THREE.SRGBColorSpace | |
| scene.environment = texture | |
| scene.background = texture | |
| scene.backgroundBlurriness = BACKGROUND_BLURRINESS | |
| scene.environmentRotation = new THREE.Euler(0, Math.PI / 2, 0) | |
| scene.backgroundRotation = new THREE.Euler(0, Math.PI / 2, 0) | |
| applyIntensity() | |
| return () => { | |
| if (scene.environment === texture) scene.environment = null | |
| if (scene.background === texture) scene.background = null | |
| } | |
| }, [texture, scene, applyIntensity]) | |
| useEffect(() => { | |
| applyIntensity() | |
| }, [applyIntensity]) | |
| useImperativeHandle(ref, () => ({ | |
| setIntensity: (amount: number) => { | |
| transitionAmountRef.current = amount | |
| applyIntensity() | |
| }, | |
| }), [applyIntensity]) | |
| return null | |
| }, | |
| ) | |