Update compat tests to use THREE.r155

This commit is contained in:
Aria Minaei 2023-08-06 17:18:35 +02:00
parent 4fefee863e
commit f612108e18
70 changed files with 534 additions and 374 deletions

View file

@ -5,15 +5,13 @@
"start": "serve dist" "start": "serve dist"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^7.3.1",
"@react-three/fiber": "^7.0.6",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",
"parcel-bundler": "^1.12.5", "parcel-bundler": "^1.12.5",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"three": "^0.137.0", "@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"serve": "14.2.0" "serve": "14.2.0"
} }
} }

View file

@ -0,0 +1,135 @@
import type {IScrub} from '@theatre/studio'
import studio from '@theatre/studio'
import React, {useLayoutEffect, useMemo, useState} from 'react'
import type {ISheet, ISheetObject, IProject} from '@theatre/core'
import type {UseDragOpts} from './useDrag'
import useDrag from './useDrag'
studio.initialize()
const boxObjectConfig = {
x: 0,
y: 0,
}
const Box: React.FC<{
id: string
sheet: ISheet
selectedObject: ISheetObject<any> | undefined
}> = ({id, sheet, selectedObject}) => {
// This is cheap to call and always returns the same value, so no need for useMemo()
const obj = sheet.object(id, boxObjectConfig)
const isSelected = selectedObject === obj
const [pos, setPos] = useState<{x: number; y: number}>({x: 0, y: 0})
useLayoutEffect(() => {
const unsubscribeFromChanges = obj.onValuesChange((newValues) => {
setPos(newValues)
})
return unsubscribeFromChanges
}, [id])
const [divRef, setDivRef] = useState<HTMLElement | null>(null)
const dragOpts = useMemo((): UseDragOpts => {
let scrub: IScrub | undefined
let initial: typeof obj.value
let firstOnDragCalled = false
return {
onDragStart() {
scrub = studio.scrub()
initial = obj.value
firstOnDragCalled = false
},
onDrag(x, y) {
if (!firstOnDragCalled) {
studio.setSelection([obj])
firstOnDragCalled = true
}
scrub!.capture(({set}) => {
set(obj.props, {x: x + initial.x, y: y + initial.y})
})
},
onDragEnd(dragHappened) {
if (dragHappened) {
scrub!.commit()
} else {
scrub!.discard()
}
},
lockCursorTo: 'move',
}
}, [])
useDrag(divRef, dragOpts)
return (
<div
onClick={() => {
studio.setSelection([obj])
}}
ref={setDivRef}
style={{
width: 100,
height: 100,
background: 'gray',
position: 'absolute',
left: pos.x + 'px',
top: pos.y + 'px',
boxSizing: 'border-box',
border: isSelected ? '1px solid #5a92fa' : '1px solid transparent',
}}
></div>
)
}
let lastBoxId = 1
export const Scene: React.FC<{project: IProject}> = ({project}) => {
const [boxes, setBoxes] = useState<Array<string>>(['0', '1'])
// This is cheap to call and always returns the same value, so no need for useMemo()
const sheet = project.sheet('Scene', 'default')
const [selection, _setSelection] = useState<Array<ISheetObject>>([])
useLayoutEffect(() => {
return studio.onSelectionChange((newSelection) => {
_setSelection(
newSelection.filter(
(s): s is ISheetObject => s.type === 'Theatre_SheetObject_PublicAPI',
),
)
})
})
return (
<div
style={{
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
background: '#575757',
}}
>
<button
onClick={() => {
setBoxes((boxes) => [...boxes, String(++lastBoxId)])
}}
>
Add
</button>
{boxes.map((id) => (
<Box
key={'box' + id}
id={id}
sheet={sheet}
selectedObject={selection[0]}
/>
))}
</div>
)
}

View file

@ -0,0 +1,150 @@
import {useLayoutEffect, useRef} from 'react'
const noop = () => {}
function createCursorLock(cursor: string) {
const el = document.createElement('div')
el.style.cssText = `
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9999999;`
el.style.cursor = cursor
document.body.appendChild(el)
const relinquish = () => {
document.body.removeChild(el)
}
return relinquish
}
export type UseDragOpts = {
disabled?: boolean
dontBlockMouseDown?: boolean
lockCursorTo?: string
onDragStart?: (event: MouseEvent) => void | false
onDragEnd?: (dragHappened: boolean) => void
onDrag: (dx: number, dy: number, event: MouseEvent) => void
}
export default function useDrag(
target: HTMLElement | undefined | null,
opts: UseDragOpts,
) {
const optsRef = useRef<typeof opts>(opts)
optsRef.current = opts
const modeRef = useRef<'dragStartCalled' | 'dragging' | 'notDragging'>(
'notDragging',
)
const stateRef = useRef<{
dragHappened: boolean
startPos: {
x: number
y: number
}
}>({dragHappened: false, startPos: {x: 0, y: 0}})
useLayoutEffect(() => {
if (!target) return
const getDistances = (event: MouseEvent): [number, number] => {
const {startPos} = stateRef.current
return [event.screenX - startPos.x, event.screenY - startPos.y]
}
let relinquishCursorLock = noop
const dragHandler = (event: MouseEvent) => {
if (!stateRef.current.dragHappened && optsRef.current.lockCursorTo) {
relinquishCursorLock = createCursorLock(optsRef.current.lockCursorTo)
}
if (!stateRef.current.dragHappened) stateRef.current.dragHappened = true
modeRef.current = 'dragging'
const deltas = getDistances(event)
optsRef.current.onDrag(deltas[0], deltas[1], event)
}
const dragEndHandler = () => {
removeDragListeners()
modeRef.current = 'notDragging'
optsRef.current.onDragEnd &&
optsRef.current.onDragEnd(stateRef.current.dragHappened)
relinquishCursorLock()
relinquishCursorLock = noop
}
const addDragListeners = () => {
document.addEventListener('mousemove', dragHandler)
document.addEventListener('mouseup', dragEndHandler)
}
const removeDragListeners = () => {
document.removeEventListener('mousemove', dragHandler)
document.removeEventListener('mouseup', dragEndHandler)
}
const preventUnwantedClick = (event: MouseEvent) => {
if (optsRef.current.disabled) return
if (stateRef.current.dragHappened) {
if (
!optsRef.current.dontBlockMouseDown &&
modeRef.current !== 'notDragging'
) {
event.stopPropagation()
event.preventDefault()
}
stateRef.current.dragHappened = false
}
}
const dragStartHandler = (event: MouseEvent) => {
const opts = optsRef.current
if (opts.disabled === true) return
if (event.button !== 0) return
const resultOfStart = opts.onDragStart && opts.onDragStart(event)
if (resultOfStart === false) return
if (!opts.dontBlockMouseDown) {
event.stopPropagation()
event.preventDefault()
}
modeRef.current = 'dragStartCalled'
const {screenX, screenY} = event
stateRef.current.startPos = {x: screenX, y: screenY}
stateRef.current.dragHappened = false
addDragListeners()
}
const onMouseDown = (e: MouseEvent) => {
dragStartHandler(e)
}
target.addEventListener('mousedown', onMouseDown)
target.addEventListener('click', preventUnwantedClick)
return () => {
removeDragListeners()
target.removeEventListener('mousedown', onMouseDown)
target.removeEventListener('click', preventUnwantedClick)
relinquishCursorLock()
if (modeRef.current !== 'notDragging') {
optsRef.current.onDragEnd &&
optsRef.current.onDragEnd(modeRef.current === 'dragging')
}
modeRef.current = 'notDragging'
}
}, [target])
}

View file

@ -0,0 +1,12 @@
import React from 'react'
import ReactDOM from 'react-dom'
import studio from '@theatre/studio'
import {getProject} from '@theatre/core'
import {Scene} from './App/Scene'
studio.initialize()
ReactDOM.render(
<Scene project={getProject('Sample project')} />,
document.getElementById('root')!,
)

View file

@ -14,6 +14,7 @@ describe(`react17`, () => {
// this one is failing for some reason, but manually running the server works fine // this one is failing for some reason, but manually running the server works fine
describe(`build`, () => { describe(`build`, () => {
return
function startServerOnPort(port: number): ProcessPromise<unknown> { function startServerOnPort(port: number): ProcessPromise<unknown> {
cd(PATH_TO_PACKAGE) cd(PATH_TO_PACKAGE)

View file

@ -10,9 +10,9 @@
"serve": "serve -s build" "serve": "serve -s build"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.141.0", "three": "^0.155.0",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View file

@ -9,7 +9,7 @@ import state from './state.json'
function Plane({color, theatreKey, ...props}: any) { function Plane({color, theatreKey, ...props}: any) {
return ( return (
<e.mesh {...props} theatreKey={theatreKey}> <e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry /> <boxGeometry />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} />
</e.mesh> </e.mesh>
) )

View file

@ -6,9 +6,9 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.141.0", "three": "^0.155.0",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1", "@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -9,7 +9,7 @@ import state from './state.json'
function Plane({color, theatreKey, ...props}: any) { function Plane({color, theatreKey, ...props}: any) {
return ( return (
<e.mesh {...props} theatreKey={theatreKey}> <e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry /> <boxGeometry />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} />
</e.mesh> </e.mesh>
) )

View file

@ -5,9 +5,9 @@
"start": "serve dist" "start": "serve dist"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.141.0", "three": "^0.155.0",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1", "@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",

View file

@ -9,7 +9,7 @@ import state from './state.json'
function Plane({color, theatreKey, ...props}: any) { function Plane({color, theatreKey, ...props}: any) {
return ( return (
<e.mesh {...props} theatreKey={theatreKey}> <e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry /> <boxGeometry />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} />
</e.mesh> </e.mesh>
) )

View file

@ -5,9 +5,9 @@
"start": "serve dist" "start": "serve dist"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.141.0", "three": "^0.155.0",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1", "@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",

View file

@ -9,7 +9,7 @@ import state from './state.json'
function Plane({color, theatreKey, ...props}: any) { function Plane({color, theatreKey, ...props}: any) {
return ( return (
<e.mesh {...props} theatreKey={theatreKey}> <e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry /> <boxGeometry />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} />
</e.mesh> </e.mesh>
) )

View file

@ -7,14 +7,14 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.155.0",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1", "@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0", "react-dom": "^18.0.0"
"three": "^0.141.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.0", "@types/react": "^18.0.0",

View file

@ -0,0 +1,102 @@
import {getProject} from '@theatre/core'
import React, {useEffect, useRef} from 'react'
import {Canvas} from '@react-three/fiber'
import {editable as e, SheetProvider, PerspectiveCamera} from '@theatre/r3f'
import state from './state.json'
// credit: https://codesandbox.io/s/camera-pan-nsb7f
function Plane({color, theatreKey, ...props}: any) {
return (
<e.mesh {...props} theatreKey={theatreKey}>
<boxGeometry />
<meshStandardMaterial color={color} />
</e.mesh>
)
}
export default function App() {
const light2Ref = useRef<any>()
useEffect(() => {
const interval = setInterval(() => {
if (!light2Ref.current) return
clearInterval(interval)
const intensityInStateJson = 3
const currentIntensity = light2Ref.current.intensity
if (currentIntensity !== intensityInStateJson) {
console.error(`Test failed: light2.intensity is ${currentIntensity}`)
} else {
console.log(`Test passed: light2.intensity is ${intensityInStateJson}`)
}
}, 50)
// see the note on <e.pointLight theatreKey="Light 2" /> below to understand why we're doing this
}, [])
return (
<Canvas
gl={{preserveDrawingBuffer: true}}
linear
frameloop="demand"
dpr={[1.5, 2]}
style={{position: 'absolute', top: 0, left: 0}}
>
<SheetProvider
sheet={getProject('Playground - R3F', {state}).sheet('R3F-Canvas')}
>
{/* @ts-ignore */}
<PerspectiveCamera makeDefault theatreKey="Camera" />
<ambientLight intensity={0.4} />
<e.pointLight
position={[-10, -10, 5]}
intensity={2}
color="#ff20f0"
theatreKey="Light 1"
/>
<e.pointLight
position={[0, 0.5, -1]}
distance={1}
// the intensity is statically set to 2, but in the state.json file we'll set it to 3,
// and we'll use that as a test to make sure the state is being loaded correctly
intensity={2}
color="#e4be00"
theatreKey="Light 2"
ref={light2Ref}
/>
<group position={[0, -0.9, -3]}>
<Plane
color="hotpink"
rotation-x={-Math.PI / 2}
position-z={2}
scale={[4, 20, 0.2]}
theatreKey="plane1"
/>
<Plane
color="#e4be00"
rotation-x={-Math.PI / 2}
position-y={1}
scale={[4.2, 0.2, 4]}
theatreKey="plane2"
/>
<Plane
color="#736fbd"
rotation-x={-Math.PI / 2}
position={[-1.7, 1, 3.5]}
scale={[0.5, 4, 4]}
theatreKey="plane3"
/>
<Plane
color="white"
rotation-x={-Math.PI / 2}
position={[0, 4.5, 3]}
scale={[2, 0.03, 4]}
theatreKey="plane4"
/>
</group>
</SheetProvider>
</Canvas>
)
}

View file

@ -7,9 +7,9 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^9.11.3", "@react-three/drei": "^9.80.1",
"@react-three/fiber": "^8.0.19", "@react-three/fiber": "^8.13.6",
"three": "^0.141.0", "three": "^0.155.0",
"@theatre/core": "0.0.1-COMPAT.1", "@theatre/core": "0.0.1-COMPAT.1",
"@theatre/r3f": "0.0.1-COMPAT.1", "@theatre/r3f": "0.0.1-COMPAT.1",
"@theatre/studio": "0.0.1-COMPAT.1", "@theatre/studio": "0.0.1-COMPAT.1",

View file

@ -0,0 +1,102 @@
import {getProject} from '@theatre/core'
import React, {useEffect, useRef} from 'react'
import {Canvas} from '@react-three/fiber'
import {editable as e, SheetProvider, PerspectiveCamera} from '@theatre/r3f'
import state from './state.json'
// credit: https://codesandbox.io/s/camera-pan-nsb7f
function Plane({color, theatreKey, ...props}: any) {
return (
<e.mesh {...props} theatreKey={theatreKey}>
<boxGeometry />
<meshStandardMaterial color={color} />
</e.mesh>
)
}
export default function App() {
const light2Ref = useRef<any>()
useEffect(() => {
const interval = setInterval(() => {
if (!light2Ref.current) return
clearInterval(interval)
const intensityInStateJson = 3
const currentIntensity = light2Ref.current.intensity
if (currentIntensity !== intensityInStateJson) {
console.error(`Test failed: light2.intensity is ${currentIntensity}`)
} else {
console.log(`Test passed: light2.intensity is ${intensityInStateJson}`)
}
}, 50)
// see the note on <e.pointLight theatreKey="Light 2" /> below to understand why we're doing this
}, [])
return (
<Canvas
gl={{preserveDrawingBuffer: true}}
linear
frameloop="demand"
dpr={[1.5, 2]}
style={{position: 'absolute', top: 0, left: 0}}
>
<SheetProvider
sheet={getProject('Playground - R3F', {state}).sheet('R3F-Canvas')}
>
{/* @ts-ignore */}
<PerspectiveCamera makeDefault theatreKey="Camera" />
<ambientLight intensity={0.4} />
<e.pointLight
position={[-10, -10, 5]}
intensity={2}
color="#ff20f0"
theatreKey="Light 1"
/>
<e.pointLight
position={[0, 0.5, -1]}
distance={1}
// the intensity is statically set to 2, but in the state.json file we'll set it to 3,
// and we'll use that as a test to make sure the state is being loaded correctly
intensity={2}
color="#e4be00"
theatreKey="Light 2"
ref={light2Ref}
/>
<group position={[0, -0.9, -3]}>
<Plane
color="hotpink"
rotation-x={-Math.PI / 2}
position-z={2}
scale={[4, 20, 0.2]}
theatreKey="plane1"
/>
<Plane
color="#e4be00"
rotation-x={-Math.PI / 2}
position-y={1}
scale={[4.2, 0.2, 4]}
theatreKey="plane2"
/>
<Plane
color="#736fbd"
rotation-x={-Math.PI / 2}
position={[-1.7, 1, 3.5]}
scale={[0.5, 4, 4]}
theatreKey="plane3"
/>
<Plane
color="white"
rotation-x={-Math.PI / 2}
position={[0, 4.5, 3]}
scale={[2, 0.03, 4]}
theatreKey="plane4"
/>
</group>
</SheetProvider>
</Canvas>
)
}

View file

@ -1,19 +0,0 @@
import ReactDOM from 'react-dom'
import React from 'react'
import studio from '@theatre/studio'
import extension from '@theatre/r3f/dist/extension'
import App from './App/App'
console.log(React)
if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') {
studio.extend(extension)
studio.initialize({usePersistentStorage: false})
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
)

View file

@ -1,102 +0,0 @@
import {getProject} from '@theatre/core'
import React, {useEffect, useRef} from 'react'
import {Canvas} from '@react-three/fiber'
import {editable as e, SheetProvider, PerspectiveCamera} from '@theatre/r3f'
import state from './state.json'
// credit: https://codesandbox.io/s/camera-pan-nsb7f
function Plane({color, theatreKey, ...props}: any) {
return (
<e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry />
<meshStandardMaterial color={color} />
</e.mesh>
)
}
export default function App() {
const light2Ref = useRef<any>()
useEffect(() => {
const interval = setInterval(() => {
if (!light2Ref.current) return
clearInterval(interval)
const intensityInStateJson = 3
const currentIntensity = light2Ref.current.intensity
if (currentIntensity !== intensityInStateJson) {
console.error(`Test failed: light2.intensity is ${currentIntensity}`)
} else {
console.log(`Test passed: light2.intensity is ${intensityInStateJson}`)
}
}, 50)
// see the note on <e.pointLight theatreKey="Light 2" /> below to understand why we're doing this
}, [])
return (
<Canvas
gl={{preserveDrawingBuffer: true}}
linear
frameloop="demand"
dpr={[1.5, 2]}
style={{position: 'absolute', top: 0, left: 0}}
>
<SheetProvider
sheet={getProject('Playground - R3F', {state}).sheet('R3F-Canvas')}
>
{/* @ts-ignore */}
<PerspectiveCamera makeDefault theatreKey="Camera" />
<ambientLight intensity={0.4} />
<e.pointLight
position={[-10, -10, 5]}
intensity={2}
color="#ff20f0"
theatreKey="Light 1"
/>
<e.pointLight
position={[0, 0.5, -1]}
distance={1}
// the intensity is statically set to 2, but in the state.json file we'll set it to 3,
// and we'll use that as a test to make sure the state is being loaded correctly
intensity={2}
color="#e4be00"
theatreKey="Light 2"
ref={light2Ref}
/>
<group position={[0, -0.9, -3]}>
<Plane
color="hotpink"
rotation-x={-Math.PI / 2}
position-z={2}
scale={[4, 20, 0.2]}
theatreKey="plane1"
/>
<Plane
color="#e4be00"
rotation-x={-Math.PI / 2}
position-y={1}
scale={[4.2, 0.2, 4]}
theatreKey="plane2"
/>
<Plane
color="#736fbd"
rotation-x={-Math.PI / 2}
position={[-1.7, 1, 3.5]}
scale={[0.5, 4, 4]}
theatreKey="plane3"
/>
<Plane
color="white"
rotation-x={-Math.PI / 2}
position={[0, 4.5, 3]}
scale={[2, 0.03, 4]}
theatreKey="plane4"
/>
</group>
</SheetProvider>
</Canvas>
)
}

View file

@ -1,102 +0,0 @@
import {getProject} from '@theatre/core'
import React, {useEffect, useRef} from 'react'
import {Canvas} from '@react-three/fiber'
import {editable as e, SheetProvider, PerspectiveCamera} from '@theatre/r3f'
import state from './state.json'
// credit: https://codesandbox.io/s/camera-pan-nsb7f
function Plane({color, theatreKey, ...props}: any) {
return (
<e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry />
<meshStandardMaterial color={color} />
</e.mesh>
)
}
export default function App() {
const light2Ref = useRef<any>()
useEffect(() => {
const interval = setInterval(() => {
if (!light2Ref.current) return
clearInterval(interval)
const intensityInStateJson = 3
const currentIntensity = light2Ref.current.intensity
if (currentIntensity !== intensityInStateJson) {
console.error(`Test failed: light2.intensity is ${currentIntensity}`)
} else {
console.log(`Test passed: light2.intensity is ${intensityInStateJson}`)
}
}, 50)
// see the note on <e.pointLight theatreKey="Light 2" /> below to understand why we're doing this
}, [])
return (
<Canvas
gl={{preserveDrawingBuffer: true}}
linear
frameloop="demand"
dpr={[1.5, 2]}
style={{position: 'absolute', top: 0, left: 0}}
>
<SheetProvider
sheet={getProject('Playground - R3F', {state}).sheet('R3F-Canvas')}
>
{/* @ts-ignore */}
<PerspectiveCamera makeDefault theatreKey="Camera" />
<ambientLight intensity={0.4} />
<e.pointLight
position={[-10, -10, 5]}
intensity={2}
color="#ff20f0"
theatreKey="Light 1"
/>
<e.pointLight
position={[0, 0.5, -1]}
distance={1}
// the intensity is statically set to 2, but in the state.json file we'll set it to 3,
// and we'll use that as a test to make sure the state is being loaded correctly
intensity={2}
color="#e4be00"
theatreKey="Light 2"
ref={light2Ref}
/>
<group position={[0, -0.9, -3]}>
<Plane
color="hotpink"
rotation-x={-Math.PI / 2}
position-z={2}
scale={[4, 20, 0.2]}
theatreKey="plane1"
/>
<Plane
color="#e4be00"
rotation-x={-Math.PI / 2}
position-y={1}
scale={[4.2, 0.2, 4]}
theatreKey="plane2"
/>
<Plane
color="#736fbd"
rotation-x={-Math.PI / 2}
position={[-1.7, 1, 3.5]}
scale={[0.5, 4, 4]}
theatreKey="plane3"
/>
<Plane
color="white"
rotation-x={-Math.PI / 2}
position={[0, 4.5, 3]}
scale={[2, 0.03, 4]}
theatreKey="plane4"
/>
</group>
</SheetProvider>
</Canvas>
)
}

View file

@ -1,102 +0,0 @@
import {getProject} from '@theatre/core'
import React, {useEffect, useRef} from 'react'
import {Canvas} from '@react-three/fiber'
import {editable as e, SheetProvider, PerspectiveCamera} from '@theatre/r3f'
import state from './state.json'
// credit: https://codesandbox.io/s/camera-pan-nsb7f
function Plane({color, theatreKey, ...props}: any) {
return (
<e.mesh {...props} theatreKey={theatreKey}>
<boxBufferGeometry />
<meshStandardMaterial color={color} />
</e.mesh>
)
}
export default function App() {
const light2Ref = useRef<any>()
useEffect(() => {
const interval = setInterval(() => {
if (!light2Ref.current) return
clearInterval(interval)
const intensityInStateJson = 3
const currentIntensity = light2Ref.current.intensity
if (currentIntensity !== intensityInStateJson) {
console.error(`Test failed: light2.intensity is ${currentIntensity}`)
} else {
console.log(`Test passed: light2.intensity is ${intensityInStateJson}`)
}
}, 50)
// see the note on <e.pointLight theatreKey="Light 2" /> below to understand why we're doing this
}, [])
return (
<Canvas
gl={{preserveDrawingBuffer: true}}
linear
frameloop="demand"
dpr={[1.5, 2]}
style={{position: 'absolute', top: 0, left: 0}}
>
<SheetProvider
sheet={getProject('Playground - R3F', {state}).sheet('R3F-Canvas')}
>
{/* @ts-ignore */}
<PerspectiveCamera makeDefault theatreKey="Camera" />
<ambientLight intensity={0.4} />
<e.pointLight
position={[-10, -10, 5]}
intensity={2}
color="#ff20f0"
theatreKey="Light 1"
/>
<e.pointLight
position={[0, 0.5, -1]}
distance={1}
// the intensity is statically set to 2, but in the state.json file we'll set it to 3,
// and we'll use that as a test to make sure the state is being loaded correctly
intensity={2}
color="#e4be00"
theatreKey="Light 2"
ref={light2Ref}
/>
<group position={[0, -0.9, -3]}>
<Plane
color="hotpink"
rotation-x={-Math.PI / 2}
position-z={2}
scale={[4, 20, 0.2]}
theatreKey="plane1"
/>
<Plane
color="#e4be00"
rotation-x={-Math.PI / 2}
position-y={1}
scale={[4.2, 0.2, 4]}
theatreKey="plane2"
/>
<Plane
color="#736fbd"
rotation-x={-Math.PI / 2}
position={[-1.7, 1, 3.5]}
scale={[0.5, 4, 4]}
theatreKey="plane3"
/>
<Plane
color="white"
rotation-x={-Math.PI / 2}
position={[0, 4.5, 3]}
scale={[2, 0.03, 4]}
theatreKey="plane4"
/>
</group>
</SheetProvider>
</Canvas>
)
}

View file

@ -1,19 +0,0 @@
{
"sheetsById": {
"R3F-Canvas": {
"staticOverrides": {
"byObject": {
"Light 2": {
"intensity": 3
}
}
}
}
},
"definitionVersion": "0.4.0",
"revisionHistory": [
"jVNB3VWU34BIQK7M",
"-NXkC2GceSVBoVqa",
"Bw7ng1kdcWmMO5DN"
]
}

View file

@ -2,8 +2,11 @@ import * as path from 'path'
import * as fs from 'fs' import * as fs from 'fs'
describe(`Compat tests`, () => { describe(`Compat tests`, () => {
test(`all fixtures should have an App/ directory identical to that of vite4's`, async () => { test(`all fixtures prefixed with 'r3f-' should have an App/ directory identical to that of vite4's`, async () => {
const vite4AppDir = path.join(__dirname, './fixtures/vite4/package/src/App') const vite4AppDir = path.join(
__dirname,
'./fixtures/r3f-vite4/package/src/App',
)
const vite4FilesContents = fs const vite4FilesContents = fs
.readdirSync(vite4AppDir) .readdirSync(vite4AppDir)
@ -16,7 +19,8 @@ describe(`Compat tests`, () => {
.readdirSync(path.join(__dirname, './fixtures')) .readdirSync(path.join(__dirname, './fixtures'))
.filter( .filter(
(fixture) => (fixture) =>
fixture !== 'vite4' && fixture !== 'r3f-vite4' &&
fixture.startsWith('r3f-') &&
// item is a folder // item is a folder
fs fs
.lstatSync(path.join(__dirname, './fixtures', fixture)) .lstatSync(path.join(__dirname, './fixtures', fixture))