Various improvements to SnapshotEditor
This commit is contained in:
parent
f06f18f838
commit
067a7cb145
7 changed files with 129 additions and 45 deletions
|
@ -46,9 +46,11 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
useVal(editorObject?.props.viewport.shading) ?? 'rendered'
|
useVal(editorObject?.props.viewport.shading) ?? 'rendered'
|
||||||
|
|
||||||
const sceneProxy = useMemo(() => sceneSnapshot?.clone(), [sceneSnapshot])
|
const sceneProxy = useMemo(() => sceneSnapshot?.clone(), [sceneSnapshot])
|
||||||
const [editableProxies, setEditableProxies] = useState<{
|
const [editableProxies, setEditableProxies] = useState<
|
||||||
[name: string]: IEditableProxy
|
{
|
||||||
}>({})
|
[name in string]?: IEditableProxy
|
||||||
|
}
|
||||||
|
>({})
|
||||||
|
|
||||||
// set up scene proxies
|
// set up scene proxies
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -86,15 +88,13 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
}, [orbitControlsRef, sceneProxy])
|
}, [orbitControlsRef, sceneProxy])
|
||||||
|
|
||||||
const selected = useSelected()
|
const selected = useSelected()
|
||||||
|
const editableProxyOfSelected = selected && editableProxies[selected]
|
||||||
|
|
||||||
// subscribe to external changes
|
// subscribe to external changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selected) {
|
if (!editableProxyOfSelected) return
|
||||||
return
|
const object = editableProxyOfSelected.object
|
||||||
}
|
const sheetObject = editableProxyOfSelected.sheetObject
|
||||||
|
|
||||||
const object = editableProxies[selected].object
|
|
||||||
const sheetObject = editableProxies[selected].sheetObject
|
|
||||||
|
|
||||||
const setFromTheatre = (newValues: any) => {
|
const setFromTheatre = (newValues: any) => {
|
||||||
object.position.set(
|
object.position.set(
|
||||||
|
@ -117,7 +117,7 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
return () => {
|
return () => {
|
||||||
untap()
|
untap()
|
||||||
}
|
}
|
||||||
}, [editableProxies, selected])
|
}, [editableProxyOfSelected, selected])
|
||||||
|
|
||||||
// set up viewport shading modes
|
// set up viewport shading modes
|
||||||
const [renderMaterials, setRenderMaterials] = useState<{
|
const [renderMaterials, setRenderMaterials] = useState<{
|
||||||
|
@ -219,15 +219,15 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<primitive object={sceneProxy} />
|
<primitive object={sceneProxy} />
|
||||||
{selected && (
|
{selected && editableProxyOfSelected && (
|
||||||
<TransformControls
|
<TransformControls
|
||||||
mode={transformControlsMode}
|
mode={transformControlsMode}
|
||||||
space={transformControlsSpace}
|
space={transformControlsSpace}
|
||||||
orbitControlsRef={orbitControlsRef}
|
orbitControlsRef={orbitControlsRef}
|
||||||
object={editableProxies[selected].object}
|
object={editableProxyOfSelected.object}
|
||||||
onObjectChange={() => {
|
onObjectChange={() => {
|
||||||
const sheetObject = editableProxies[selected].sheetObject
|
const sheetObject = editableProxyOfSelected.sheetObject
|
||||||
const obj = editableProxies[selected].object
|
const obj = editableProxyOfSelected.object
|
||||||
|
|
||||||
studio.transaction(({set}) => {
|
studio.transaction(({set}) => {
|
||||||
set(sheetObject.props, {
|
set(sheetObject.props, {
|
||||||
|
@ -252,7 +252,9 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
onDraggingChange={(event) => (isBeingEdited.current = event.value)}
|
onDraggingChange={(event) => (isBeingEdited.current = event.value)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{Object.values(editableProxies).map(({portal}) => portal)}
|
{Object.values(editableProxies).map(
|
||||||
|
(editableProxy) => editableProxy!.portal,
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type {VFC} from 'react'
|
import {useState} from 'react'
|
||||||
import {useLayoutEffect} from 'react'
|
import {useLayoutEffect} from 'react'
|
||||||
import React, {useEffect, useRef} from 'react'
|
import React, {useEffect, useRef} from 'react'
|
||||||
import {Canvas} from '@react-three/fiber'
|
import {Canvas} from '@react-three/fiber'
|
||||||
|
@ -10,6 +10,9 @@ import ProxyManager from './ProxyManager'
|
||||||
import studio from '@theatre/studio'
|
import studio from '@theatre/studio'
|
||||||
import {useVal} from '@theatre/dataverse-react'
|
import {useVal} from '@theatre/dataverse-react'
|
||||||
import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components'
|
import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components'
|
||||||
|
import IconButton from './Toolbar/utils/IconButton'
|
||||||
|
import {BiRefresh} from 'react-icons/bi'
|
||||||
|
import {PortalContext} from 'reakit'
|
||||||
|
|
||||||
const GlobalStyle = createGlobalStyle`
|
const GlobalStyle = createGlobalStyle`
|
||||||
:host {
|
:host {
|
||||||
|
@ -81,9 +84,21 @@ const CanvasWrapper = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
`
|
`
|
||||||
|
|
||||||
const SnapshotEditor: VFC = () => {
|
const Overlay = styled.div`
|
||||||
console.log('Snapshot editor!!')
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 2;
|
||||||
|
pointer-events: none;
|
||||||
|
`
|
||||||
|
|
||||||
|
const Tools = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
left: 8px;
|
||||||
|
top: 6px;
|
||||||
|
pointer-events: auto;
|
||||||
|
`
|
||||||
|
|
||||||
|
const SnapshotEditor: React.FC<{}> = () => {
|
||||||
const [editorObject, sceneSnapshot, initialEditorCamera, createSnapshot] =
|
const [editorObject, sceneSnapshot, initialEditorCamera, createSnapshot] =
|
||||||
useEditorStore(
|
useEditorStore(
|
||||||
(state) => [
|
(state) => [
|
||||||
|
@ -110,6 +125,8 @@ const SnapshotEditor: VFC = () => {
|
||||||
}
|
}
|
||||||
}, [editorOpen])
|
}, [editorOpen])
|
||||||
|
|
||||||
|
const [overlay, setOverlay] = useState<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
if (!editorObject) return <></>
|
if (!editorObject) return <></>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -117,30 +134,42 @@ const SnapshotEditor: VFC = () => {
|
||||||
<StyleSheetManager disableVendorPrefixes>
|
<StyleSheetManager disableVendorPrefixes>
|
||||||
<>
|
<>
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
<Wrapper>
|
<PortalContext.Provider value={overlay}>
|
||||||
{sceneSnapshot ? (
|
<Wrapper>
|
||||||
<>
|
<Overlay ref={setOverlay}>
|
||||||
<CanvasWrapper>
|
<Tools>
|
||||||
<Canvas
|
<IconButton
|
||||||
// @ts-ignore
|
icon={<BiRefresh />}
|
||||||
colorManagement
|
label="Refresh Snapshot"
|
||||||
camera={initialEditorCamera}
|
onClick={createSnapshot}
|
||||||
onCreated={({gl}) => {
|
></IconButton>
|
||||||
gl.setClearColor('white')
|
</Tools>
|
||||||
}}
|
</Overlay>
|
||||||
shadowMap
|
|
||||||
dpr={[1, 2]}
|
{sceneSnapshot ? (
|
||||||
fog={'red'}
|
<>
|
||||||
onPointerMissed={() =>
|
<CanvasWrapper>
|
||||||
studio.__experimental_setSelection([])
|
<Canvas
|
||||||
}
|
// @ts-ignore
|
||||||
>
|
colorManagement
|
||||||
<EditorScene />
|
camera={initialEditorCamera}
|
||||||
</Canvas>
|
onCreated={({gl}) => {
|
||||||
</CanvasWrapper>
|
gl.setClearColor('white')
|
||||||
</>
|
}}
|
||||||
) : null}
|
shadowMap
|
||||||
</Wrapper>
|
dpr={[1, 2]}
|
||||||
|
fog={'red'}
|
||||||
|
onPointerMissed={() =>
|
||||||
|
studio.__experimental_setSelection([])
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<EditorScene />
|
||||||
|
</Canvas>
|
||||||
|
</CanvasWrapper>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</Wrapper>
|
||||||
|
</PortalContext.Provider>
|
||||||
</>
|
</>
|
||||||
</StyleSheetManager>
|
</StyleSheetManager>
|
||||||
</root.div>
|
</root.div>
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
"propose": "^0.0.5",
|
"propose": "^0.0.5",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-error-boundary": "^3.1.3",
|
||||||
"react-icons": "^4.2.0",
|
"react-icons": "^4.2.0",
|
||||||
"react-is": "^17.0.2",
|
"react-is": "^17.0.2",
|
||||||
"react-shadow": "^19.0.2",
|
"react-shadow": "^19.0.2",
|
||||||
|
|
|
@ -16,7 +16,7 @@ const PanelsRoot: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* {paneEls} */}
|
{paneEls}
|
||||||
<OutlinePanel />
|
<OutlinePanel />
|
||||||
<ObjectEditorPanel />
|
<ObjectEditorPanel />
|
||||||
<SequenceEditorPanel />
|
<SequenceEditorPanel />
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
import BasePanel from './BasePanel'
|
import BasePanel from './BasePanel'
|
||||||
import PanelDragZone from './PanelDragZone'
|
import PanelDragZone from './PanelDragZone'
|
||||||
import PanelWrapper from './PanelWrapper'
|
import PanelWrapper from './PanelWrapper'
|
||||||
|
import {ErrorBoundary} from 'react-error-boundary'
|
||||||
|
|
||||||
const defaultPosition: PanelPosition = {
|
const defaultPosition: PanelPosition = {
|
||||||
edges: {
|
edges: {
|
||||||
|
@ -50,6 +51,35 @@ const F2 = styled(F2Impl)`
|
||||||
position: relative;
|
position: relative;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const ErrorContainer = styled.div`
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
& > pre {
|
||||||
|
border: 1px solid #ff62624f;
|
||||||
|
background-color: rgb(255 0 0 / 5%);
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 8px;
|
||||||
|
font-family: monospace;
|
||||||
|
overflow: scroll;
|
||||||
|
color: #ff9896;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const ErrorFallback: React.FC<{error: Error}> = (props) => {
|
||||||
|
return (
|
||||||
|
<ErrorContainer>
|
||||||
|
An Error occured rendering this pane. Open the console for more info.
|
||||||
|
<pre>
|
||||||
|
{JSON.stringify(
|
||||||
|
{message: props.error.message, stack: props.error.stack},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
)}
|
||||||
|
</pre>
|
||||||
|
</ErrorContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const Content: React.FC<{paneInstance: PaneInstance<$FixMe>}> = ({
|
const Content: React.FC<{paneInstance: PaneInstance<$FixMe>}> = ({
|
||||||
paneInstance,
|
paneInstance,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -62,7 +92,9 @@ const Content: React.FC<{paneInstance: PaneInstance<$FixMe>}> = ({
|
||||||
</TitleBar>
|
</TitleBar>
|
||||||
</PanelDragZone>
|
</PanelDragZone>
|
||||||
<F2>
|
<F2>
|
||||||
<Comp id={paneInstance.instanceId} object={paneInstance.object} />
|
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||||
|
<Comp id={paneInstance.instanceId} object={paneInstance.object} />
|
||||||
|
</ErrorBoundary>
|
||||||
</F2>
|
</F2>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,7 +13,6 @@ const Container = styled.div`
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
display: none;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const GlobalToolbar: React.FC<{}> = (props) => {
|
const GlobalToolbar: React.FC<{}> = (props) => {
|
||||||
|
|
21
yarn.lock
21
yarn.lock
|
@ -1935,6 +1935,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/runtime@npm:^7.12.5":
|
||||||
|
version: 7.14.6
|
||||||
|
resolution: "@babel/runtime@npm:7.14.6"
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: ^0.13.4
|
||||||
|
checksum: dd931f6ef1c8dab295c4a00c592db6352bf12a5c443f8222304d5c1d3e88d795fa949afcb6f053eec2e69e9827a17ff274524c1cd43813f56b61e3a540274d2f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/template@npm:^7.12.13, @babel/template@npm:^7.3.3, @babel/template@npm:^7.4.4":
|
"@babel/template@npm:^7.12.13, @babel/template@npm:^7.3.3, @babel/template@npm:^7.4.4":
|
||||||
version: 7.12.13
|
version: 7.12.13
|
||||||
resolution: "@babel/template@npm:7.12.13"
|
resolution: "@babel/template@npm:7.12.13"
|
||||||
|
@ -14771,6 +14780,17 @@ fsevents@^1.2.7:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-error-boundary@npm:^3.1.3":
|
||||||
|
version: 3.1.3
|
||||||
|
resolution: "react-error-boundary@npm:3.1.3"
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime": ^7.12.5
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16.13.1"
|
||||||
|
checksum: 8b5294dd14f8d13e430e0c15d7a8fa2eede0c4d59b499303a51645b2e29c00f1ab373de07431664fe64f08362fe2ee044757ffdbad60db1a84df151dd1d4ebaf
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-icons@npm:*, react-icons@npm:^4.2.0":
|
"react-icons@npm:*, react-icons@npm:^4.2.0":
|
||||||
version: 4.2.0
|
version: 4.2.0
|
||||||
resolution: "react-icons@npm:4.2.0"
|
resolution: "react-icons@npm:4.2.0"
|
||||||
|
@ -17199,6 +17219,7 @@ fsevents@^1.2.7:
|
||||||
propose: ^0.0.5
|
propose: ^0.0.5
|
||||||
react: ^17.0.2
|
react: ^17.0.2
|
||||||
react-dom: ^17.0.2
|
react-dom: ^17.0.2
|
||||||
|
react-error-boundary: ^3.1.3
|
||||||
react-icons: ^4.2.0
|
react-icons: ^4.2.0
|
||||||
react-is: ^17.0.2
|
react-is: ^17.0.2
|
||||||
react-shadow: ^19.0.2
|
react-shadow: ^19.0.2
|
||||||
|
|
Loading…
Reference in a new issue