import { ReactThreeFiber, useFrame, useThree } from '@react-three/fiber' import * as React from 'react' import * as THREE from 'three' import { DeviceOrientationControls as DeviceOrientationControlsImp } from 'three-stdlib' import { ForwardRefComponent } from '../helpers/ts-utils' export type DeviceOrientationControlsProps = ReactThreeFiber.Object3DNode< DeviceOrientationControlsImp, typeof DeviceOrientationControlsImp > & { camera?: THREE.Camera onChange?: (e?: THREE.Event) => void makeDefault?: boolean } export const DeviceOrientationControls: ForwardRefComponent< DeviceOrientationControlsProps, DeviceOrientationControlsImp > = /* @__PURE__ */ React.forwardRef( (props: DeviceOrientationControlsProps, ref) => { const { camera, onChange, makeDefault, ...rest } = props const defaultCamera = useThree((state) => state.camera) const invalidate = useThree((state) => state.invalidate) const get = useThree((state) => state.get) const set = useThree((state) => state.set) const explCamera = camera || defaultCamera const controls = React.useMemo(() => new DeviceOrientationControlsImp(explCamera), [explCamera]) React.useEffect(() => { const callback = (e: THREE.Event) => { invalidate() if (onChange) onChange(e) } controls?.addEventListener?.('change', callback) return () => controls?.removeEventListener?.('change', callback) }, [onChange, controls, invalidate]) useFrame(() => controls?.update(), -1) React.useEffect(() => { const current = controls current?.connect() return () => current?.dispose() }, [controls]) React.useEffect(() => { if (makeDefault) { const old = get().controls set({ controls }) return () => set({ controls: old }) } }, [makeDefault, controls]) return controls ? : null } )