parent
bd110ed01a
commit
3eba08ff32
3 changed files with 71 additions and 10 deletions
44
packages/r3f/src/components/DragDetector.tsx
Normal file
44
packages/r3f/src/components/DragDetector.tsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import type {
|
||||||
|
FC,
|
||||||
|
ReactNode} from 'react';
|
||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
|
|
||||||
|
const dragDetectorContext = createContext(false)
|
||||||
|
|
||||||
|
interface DragDetectorProviderProps {
|
||||||
|
children: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DragDetectorProvider: FC<DragDetectorProviderProps> = ({
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const mouseDownRef = useRef(false)
|
||||||
|
const [dragging, setDragging] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', () => (mouseDownRef.current = true))
|
||||||
|
document.addEventListener('mousemove', () => {
|
||||||
|
if (mouseDownRef.current) {
|
||||||
|
setDragging(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.addEventListener('mouseup', () => {
|
||||||
|
mouseDownRef.current = false
|
||||||
|
setDragging(false)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<dragDetectorContext.Provider value={dragging}>
|
||||||
|
{children}
|
||||||
|
</dragDetectorContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDragDetector = () => useContext(dragDetectorContext)
|
|
@ -12,6 +12,7 @@ import type {IconID} from '../icons'
|
||||||
import icons from '../icons'
|
import icons from '../icons'
|
||||||
import type {Helper} from '../editableFactoryConfigUtils'
|
import type {Helper} from '../editableFactoryConfigUtils'
|
||||||
import {invalidate, useFrame, useThree} from '@react-three/fiber'
|
import {invalidate, useFrame, useThree} from '@react-three/fiber'
|
||||||
|
import {useDragDetector} from './DragDetector'
|
||||||
|
|
||||||
export interface EditableProxyProps {
|
export interface EditableProxyProps {
|
||||||
editableName: string
|
editableName: string
|
||||||
|
@ -28,6 +29,8 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
||||||
shallow,
|
shallow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const dragging = useDragDetector()
|
||||||
|
|
||||||
const editable = editables[uniqueName]
|
const editable = editables[uniqueName]
|
||||||
|
|
||||||
const selected = useSelected()
|
const selected = useSelected()
|
||||||
|
@ -76,6 +79,11 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
||||||
helper.update()
|
helper.update()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
if (dragging) {
|
||||||
|
setHovered(false)
|
||||||
|
}
|
||||||
|
}, [dragging])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -94,14 +102,22 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onPointerOver={(e) => {
|
onPointerOver={
|
||||||
e.stopPropagation()
|
!dragging
|
||||||
setHovered(true)
|
? (e) => {
|
||||||
}}
|
e.stopPropagation()
|
||||||
onPointerOut={(e) => {
|
setHovered(true)
|
||||||
e.stopPropagation()
|
}
|
||||||
setHovered(false)
|
: undefined
|
||||||
}}
|
}
|
||||||
|
onPointerOut={
|
||||||
|
!dragging
|
||||||
|
? (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
setHovered(false)
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<primitive object={object}>
|
<primitive object={object}>
|
||||||
{(showOverlayIcons ||
|
{(showOverlayIcons ||
|
||||||
|
|
|
@ -15,6 +15,7 @@ import useSnapshotEditorCamera from './useSnapshotEditorCamera'
|
||||||
import {getEditorSheet, getEditorSheetObject} from './editorStuff'
|
import {getEditorSheet, getEditorSheetObject} from './editorStuff'
|
||||||
import type {$IntentionalAny} from '@theatre/shared/utils/types'
|
import type {$IntentionalAny} from '@theatre/shared/utils/types'
|
||||||
import {InfiniteGridHelper} from '../InfiniteGridHelper'
|
import {InfiniteGridHelper} from '../InfiniteGridHelper'
|
||||||
|
import {DragDetectorProvider} from './DragDetector'
|
||||||
|
|
||||||
const GlobalStyle = createGlobalStyle`
|
const GlobalStyle = createGlobalStyle`
|
||||||
:host {
|
:host {
|
||||||
|
@ -54,7 +55,7 @@ const EditorScene: React.FC<{snapshotEditorSheet: ISheet; paneId: string}> = ({
|
||||||
const grid = useMemo(() => new InfiniteGridHelper(), [])
|
const grid = useMemo(() => new InfiniteGridHelper(), [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<DragDetectorProvider>
|
||||||
{showGrid && <primitive object={grid} />}
|
{showGrid && <primitive object={grid} />}
|
||||||
{showAxes && <axesHelper args={[500]} />}
|
{showAxes && <axesHelper args={[500]} />}
|
||||||
{editorCamera}
|
{editorCamera}
|
||||||
|
@ -62,7 +63,7 @@ const EditorScene: React.FC<{snapshotEditorSheet: ISheet; paneId: string}> = ({
|
||||||
<primitive object={helpersRoot}></primitive>
|
<primitive object={helpersRoot}></primitive>
|
||||||
<ProxyManager orbitControlsRef={orbitControlsRef} />
|
<ProxyManager orbitControlsRef={orbitControlsRef} />
|
||||||
<color attach="background" args={[0.24, 0.24, 0.24]} />
|
<color attach="background" args={[0.24, 0.24, 0.24]} />
|
||||||
</>
|
</DragDetectorProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue