import {useCallback, useLayoutEffect} from 'react' import React from 'react' import {Canvas} from '@react-three/fiber' import type {BaseSheetObjectType} from '../store' import {allRegisteredObjects, useEditorStore} from '../store' import shallow from 'zustand/shallow' import root from 'react-shadow/styled-components' import ProxyManager from './ProxyManager' import studio, {ToolbarIconButton} from '@theatre/studio' import {useVal} from '@theatre/react' import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components' import {IoCameraReverseOutline} from 'react-icons/all' import type {ISheet} from '@theatre/core' import useSnapshotEditorCamera from './useSnapshotEditorCamera' import {getEditorSheet, getEditorSheetObject} from './editorStuff' import type {$IntentionalAny} from '@theatre/shared/utils/types' const GlobalStyle = createGlobalStyle` :host { contain: strict; all: initial; color: white; font: 11px -apple-system, BlinkMacSystemFont, Segoe WPC, Segoe Editor, HelveticaNeue-Light, Ubuntu, Droid Sans, sans-serif; } * { padding: 0; margin: 0; font-size: 100%; font: inherit; vertical-align: baseline; list-style: none; } ` const EditorScene: React.FC<{snapshotEditorSheet: ISheet; paneId: string}> = ({ snapshotEditorSheet, paneId, }) => { const [editorCamera, orbitControlsRef] = useSnapshotEditorCamera( snapshotEditorSheet, paneId, ) const editorObject = getEditorSheetObject() const helpersRoot = useEditorStore((state) => state.helpersRoot, shallow) const showGrid = useVal(editorObject?.props.viewport.showGrid) ?? true const showAxes = useVal(editorObject?.props.viewport.showAxes) ?? true return ( <> {showGrid && } {showAxes && } {editorCamera} ) } const Wrapper = styled.div` tab-size: 4; line-height: 1.15; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ margin: 0; position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; ` const CanvasWrapper = styled.div` display: relative; z-index: 0; height: 100%; ` const Overlay = styled.div` 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<{paneId: string}> = (props) => { const snapshotEditorSheet = getEditorSheet() const paneId = props.paneId const editorObject = getEditorSheetObject() const [sceneSnapshot, createSnapshot] = useEditorStore( (state) => [state.sceneSnapshot, state.createSnapshot], shallow, ) const editorOpen = true useLayoutEffect(() => { let timeout: NodeJS.Timeout | undefined if (editorOpen) { // a hack to make sure all the scene's props are // applied before we take a snapshot timeout = setTimeout(createSnapshot, 100) } return () => { if (timeout !== undefined) { clearTimeout(timeout) } } }, [editorOpen]) const onPointerMissed = useCallback(() => { // This callback runs when the user clicks in an empty space inside a SnapshotEditor. // We'll try to set the current selection to the nearest sheet _if_ at least one object // belonging to R3F was selected previously. const obj: undefined | BaseSheetObjectType = studio.selection.find( (sheetOrObject) => allRegisteredObjects.has(sheetOrObject as $IntentionalAny), ) as $IntentionalAny if (obj) { studio.setSelection([obj.sheet]) } }, []) if (!editorObject) return <> return ( <> {sceneSnapshot ? ( <> { gl.setClearColor('white') }} shadowMap dpr={[1, 2]} fog={'red'} frameloop="demand" onPointerMissed={onPointerMissed} > ) : null} {/* */} ) } export default SnapshotEditor