r3f sheets are now re-usable

This commit is contained in:
Aria Minaei 2021-09-05 23:33:17 +02:00
parent 7af470a053
commit 5295f9ae91
5 changed files with 23 additions and 22 deletions

View file

@ -1,4 +1,4 @@
import {editable as e, Wrapper} from '@theatre/plugin-r3f' import {editable as e, SheetProvider} from '@theatre/plugin-r3f'
import {getProject} from '@theatre/core' import {getProject} from '@theatre/core'
import * as THREE from 'three' import * as THREE from 'three'
import React, {useState, useEffect, useRef} from 'react' import React, {useState, useEffect, useRef} from 'react'
@ -90,7 +90,7 @@ function App() {
// @ts-ignore // @ts-ignore
shadowMap shadowMap
> >
<Wrapper <SheetProvider
getSheet={() => getProject('Playground - R3F').sheet('R3F-Canvas')} getSheet={() => getProject('Playground - R3F').sheet('R3F-Canvas')}
> >
{/* @ts-ignore */} {/* @ts-ignore */}
@ -140,7 +140,7 @@ function App() {
/> />
</group> </group>
<Button /> <Button />
</Wrapper> </SheetProvider>
</Canvas> </Canvas>
</div> </div>
) )

View file

@ -1,7 +1,7 @@
import { import {
editable as e, editable as e,
RefreshSnapshot, RefreshSnapshot,
Wrapper, SheetProvider,
extension, extension,
} from '@theatre/plugin-r3f' } from '@theatre/plugin-r3f'
import {OrbitControls, Stars} from '@react-three/drei' import {OrbitControls, Stars} from '@react-three/drei'
@ -61,7 +61,7 @@ function App() {
return ( return (
<div onClick={() => setBgIndex((bgIndex) => (bgIndex + 1) % bgs.length)}> <div onClick={() => setBgIndex((bgIndex) => (bgIndex + 1) % bgs.length)}>
<Canvas dpr={[1.5, 2]} linear shadows frameloop="demand"> <Canvas dpr={[1.5, 2]} linear shadows frameloop="demand">
<Wrapper getSheet={() => getProject('Space').sheet('Scene')}> <SheetProvider getSheet={() => getProject('Space').sheet('Scene')}>
<fog attach="fog" args={[bg, 16, 30]} /> <fog attach="fog" args={[bg, 16, 30]} />
<color attach="background" args={[bg]} /> <color attach="background" args={[bg]} />
<ambientLight intensity={0.75} /> <ambientLight intensity={0.75} />
@ -99,7 +99,7 @@ function App() {
minPolarAngle={Math.PI / 2} minPolarAngle={Math.PI / 2}
/> />
<Stars radius={500} depth={50} count={1000} factor={10} /> <Stars radius={500} depth={50} count={1000} factor={10} />
</Wrapper> </SheetProvider>
</Canvas> </Canvas>
</div> </div>
) )

View file

@ -10,13 +10,21 @@ import {bindToCanvas} from './store'
const ctx = createContext<{sheet: ISheet | undefined} | undefined>(undefined) const ctx = createContext<{sheet: ISheet | undefined} | undefined>(undefined)
export const useWrapperContext = (): const useWrapperContext = (): {sheet: ISheet | undefined} => {
| {sheet: ISheet | undefined} const val = useContext(ctx)
| undefined => { if (!val) {
return useContext(ctx) throw new Error(
`No sheet found. You need to add a <SheetProvider> higher up in the tree. https://docs.theatrejs.com/r3f.html#sheetprovider`,
)
}
return val
} }
const Wrapper: React.FC<{ export const useCurrentSheet = (): ISheet | undefined => {
return useWrapperContext().sheet
}
const SheetProvider: React.FC<{
getSheet: () => ISheet getSheet: () => ISheet
}> = (props) => { }> = (props) => {
const {scene, gl} = useThree((s) => ({scene: s.scene, gl: s.gl})) const {scene, gl} = useThree((s) => ({scene: s.scene, gl: s.gl}))
@ -36,4 +44,4 @@ const Wrapper: React.FC<{
return <ctx.Provider value={{sheet}}>{props.children}</ctx.Provider> return <ctx.Provider value={{sheet}}>{props.children}</ctx.Provider>
} }
export default Wrapper export default SheetProvider

View file

@ -18,7 +18,7 @@ import mergeRefs from 'react-merge-refs'
import type {$FixMe} from '@theatre/shared/utils/types' import type {$FixMe} from '@theatre/shared/utils/types'
import type {ISheetObject} from '@theatre/core' import type {ISheetObject} from '@theatre/core'
import useInvalidate from './useInvalidate' import useInvalidate from './useInvalidate'
import {useWrapperContext} from '../Wrapper' import {useCurrentSheet} from '../SheetProvider'
interface Elements { interface Elements {
group: Group group: Group
@ -51,14 +51,7 @@ const editable = <
({uniqueName, visible, editableType, ...props}: Props, ref) => { ({uniqueName, visible, editableType, ...props}: Props, ref) => {
const objectRef = useRef<Elements[U]>() const objectRef = useRef<Elements[U]>()
const wrapperContext = useWrapperContext() const sheet = useCurrentSheet()
if (!wrapperContext) {
throw new Error(
`Editable components must be a descendent of a <Wrapper>`,
)
}
const {sheet} = wrapperContext
const [sheetObject, setSheetObject] = useState< const [sheetObject, setSheetObject] = useState<
undefined | ISheetObject<$FixMe> undefined | ISheetObject<$FixMe>

View file

@ -3,6 +3,6 @@ export {default as EditorHelper} from './components/EditorHelper'
export type {EditorHelperProps} from './components/EditorHelper' export type {EditorHelperProps} from './components/EditorHelper'
export {default as editable} from './components/editable' export {default as editable} from './components/editable'
export type {EditableState, BindFunction} from './store' export type {EditableState, BindFunction} from './store'
export {default as Wrapper} from './Wrapper' export {default as SheetProvider, useCurrentSheet} from './SheetProvider'
export {default as useRefreshSnapshot} from './components/useRefreshSnapshot' export {default as useRefreshSnapshot} from './components/useRefreshSnapshot'
export {default as RefreshSnapshot} from './components/RefreshSnapshot' export {default as RefreshSnapshot} from './components/RefreshSnapshot'