Various improvements to SnapshotEditor

This commit is contained in:
Aria Minaei 2021-07-16 15:06:15 +02:00
parent f06f18f838
commit 067a7cb145
7 changed files with 129 additions and 45 deletions

View file

@ -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,
)}
</> </>
) )
} }

View file

@ -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>

View file

@ -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",

View file

@ -16,7 +16,7 @@ const PanelsRoot: React.FC = () => {
return ( return (
<> <>
{/* {paneEls} */} {paneEls}
<OutlinePanel /> <OutlinePanel />
<ObjectEditorPanel /> <ObjectEditorPanel />
<SequenceEditorPanel /> <SequenceEditorPanel />

View file

@ -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>
) )

View file

@ -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) => {

View file

@ -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