diff --git a/packages/plugin-r3f/src/components/Editor.tsx b/packages/plugin-r3f/src/components/Editor.tsx index 2ab252f..3efd795 100644 --- a/packages/plugin-r3f/src/components/Editor.tsx +++ b/packages/plugin-r3f/src/components/Editor.tsx @@ -1,4 +1,5 @@ import type {VFC} from 'react' +import {useLayoutEffect} from 'react' import React, {useEffect, useRef, Suspense} from 'react' import {Canvas} from '@react-three/fiber' import {useEditorStore} from '../store' @@ -8,8 +9,9 @@ import root from 'react-shadow' import styles from '../bundle.css.txt' import UI from './UI' import ProxyManager from './ProxyManager' -import {Button, Heading, Code, PortalManager, IdProvider} from './elements' +import {Button, PortalManager, IdProvider} from './elements' import studio from '@theatre/studio' +import {useVal} from '@theatre/dataverse-react' const EditorScene = () => { const orbitControlsRef = useRef() @@ -60,24 +62,25 @@ const EditorScene = () => { } const Editor: VFC = () => { - const [ - sceneSnapshot, - editorOpen, - initialState, - initialEditorCamera, - setEditorOpen, - createSnapshot, - ] = useEditorStore( - (state) => [ - state.sceneSnapshot, - state.editorOpen, - state.initialState, - state.initialEditorCamera, - state.setEditorOpen, - state.createSnapshot, - ], - shallow, - ) + const [editorObject, sceneSnapshot, initialEditorCamera, createSnapshot] = + useEditorStore( + (state) => [ + state.editorObject, + state.sceneSnapshot, + state.initialEditorCamera, + state.createSnapshot, + ], + shallow, + ) + + const editorOpen = !!useVal(editorObject?.props._isOpen) + useLayoutEffect(() => { + if (editorOpen) { + createSnapshot() + } + }, [editorOpen]) + + if (!editorObject) return <> return ( @@ -110,67 +113,15 @@ const Editor: VFC = () => { - ) : ( -
-
- - No canvas connected - -
- Please use configure() and{' '} - bind() to connect a canvas to React Three - Editable. -
- - {`import React from 'react'; -import { Canvas } from '@react-three/fiber'; -import { configure, editable as e } from 'react-three-editable'; - -const bind = configure({ - localStorageNamespace: "MyProject" -}); - -const MyComponent = () => ( - - - - - - -);`} - -
- For more details, please consult the{' '} - - documentation - - . -
- -
-
- )} + ) : null} {editorOpen || ( diff --git a/packages/plugin-r3f/src/store.ts b/packages/plugin-r3f/src/store.ts index 14e4d28..a710449 100644 --- a/packages/plugin-r3f/src/store.ts +++ b/packages/plugin-r3f/src/store.ts @@ -137,7 +137,7 @@ export interface EditableState { export type EditorStore = { sheet: ISheet | null - uiSheet: ISheet | null + editorObject: ISheetObject | null sheetObjects: {[uniqueName in string]?: BaseSheetObjectType} scene: Scene | null gl: WebGLRenderer | null @@ -152,7 +152,6 @@ export type EditorStore = { transformControlsMode: TransformControlsMode transformControlsSpace: TransformControlsSpace viewportShading: ViewportShading - editorOpen: boolean sceneSnapshot: Scene | null editablesSnapshot: Record | null hdrPaths: string[] @@ -170,7 +169,7 @@ export type EditorStore = { allowImplicitInstancing: boolean, editorCamera: ContainerProps['camera'], sheet: ISheet, - uiSheet: null | ISheet, + editorObject: null | ISheetObject, ) => void setOrbitControlsRef: ( @@ -187,7 +186,6 @@ export type EditorStore = { setShowGrid: (show: boolean) => void setShowAxes: (show: boolean) => void setReferenceWindowSize: (size: number) => void - setEditorOpen: (open: boolean) => void createSnapshot: () => void setSheetObject: (uniqueName: string, sheetObject: BaseSheetObjectType) => void setSnapshotProxyObject: ( @@ -214,7 +212,7 @@ const config: StateCreator = (set, get) => { return { sheet: null, - uiSheet: null, + editorObject: null, sheetObjects: {}, scene: null, gl: null, @@ -228,7 +226,6 @@ const config: StateCreator = (set, get) => { transformControlsMode: 'translate', transformControlsSpace: 'world', viewportShading: 'rendered', - editorOpen: false, sceneSnapshot: null, editablesSnapshot: null, hdrPaths: [], @@ -246,7 +243,7 @@ const config: StateCreator = (set, get) => { allowImplicitInstancing, editorCamera, sheet, - uiSheet, + editorObject, ) => { set({ scene, @@ -254,7 +251,7 @@ const config: StateCreator = (set, get) => { allowImplicitInstancing, initialEditorCamera: editorCamera, sheet, - uiSheet, + editorObject, }) }, @@ -339,9 +336,6 @@ const config: StateCreator = (set, get) => { set({showAxes: show}) }, setReferenceWindowSize: (size) => set({referenceWindowSize: size}), - setEditorOpen: (open) => { - set({editorOpen: open}) - }, createSnapshot: () => { set((state) => ({ sceneSnapshot: state.scene?.clone() ?? null, @@ -370,6 +364,12 @@ export type BindFunction = (options: { sheet: ISheet }) => (options: {gl: WebGLRenderer; scene: Scene}) => void +const editorSheetObjectConfig = { + props: types.compound({ + _isOpen: types.number(0), + }), +} + export const bindToCanvas: BindFunction = ({ allowImplicitInstancing = false, editorCamera = {}, @@ -380,6 +380,9 @@ export const bindToCanvas: BindFunction = ({ ? getProject('R3F Plugin').sheet('UI') : null + const editorSheetObject = + uiSheet?.object('Editor', null, editorSheetObjectConfig) || null + return ({gl, scene}) => { const init = useEditorStore.getState().init init( @@ -388,7 +391,7 @@ export const bindToCanvas: BindFunction = ({ allowImplicitInstancing, {...{position: [20, 20, 20]}, ...editorCamera}, sheet, - uiSheet, + editorSheetObject, ) } }