Add variants of the extension example

This commit is contained in:
Cole Lawrence 2022-07-22 11:55:52 -04:00
parent 984a61347f
commit fcc23b3863
5 changed files with 243 additions and 30 deletions

View file

@ -0,0 +1,37 @@
import {editable as e, SheetProvider} from '@theatre/r3f'
import {Stars, TorusKnot} from '@react-three/drei'
import {getProject} from '@theatre/core'
import React from 'react'
import {Canvas} from '@react-three/fiber'
function App() {
return (
<div
onClick={() => {
// return setBgIndex((bgIndex) => (bgIndex + 1) % bgs.length)
}}
style={{
height: '100vh',
}}
>
<Canvas
dpr={[1.5, 2]}
linear
gl={{preserveDrawingBuffer: true}}
frameloop="demand"
>
<SheetProvider sheet={getProject('Space').sheet('Scene')}>
<ambientLight intensity={0.75} />
<e.group uniqueName="trefoil">
<TorusKnot scale={[1, 1, 1]} args={[1, 0.3, 128, 64]}>
<meshNormalMaterial />
</TorusKnot>
</e.group>
<Stars radius={500} depth={50} count={1000} factor={10} />
</SheetProvider>
</Canvas>
</div>
)
}
export default App

View file

@ -0,0 +1,70 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import type {ToolsetConfig} from '@theatre/studio'
import studio from '@theatre/studio'
import extension from '@theatre/r3f/dist/extension'
import {Box, prism, Ticker, val} from '@theatre/dataverse'
/**
* Let's take a look at how we can use `prism`, `Ticker`, and `val` from Theatre.js's Dataverse library
* to create a switch with state that is updated automatically,
* and is even stored in a Theatre.js object.
*
* Without going into the details of `prism`, `Ticker`, and `val`, note that by wrapping our `ToolsetConfig` in a prism, our
* ```ts
* ... .tapImmediate(Ticker.raf, (toolset) => {
* set(toolset)
* })
* ```
* code will be called whenever `val(obj.props.exampleProp)` changes (whenever the user clicks the switch and the `onChange` callback is called).
* This will ensure that our switch's value matches its state and is reflected in the UI via `set(toolset)`.
*/
studio.extend(extension)
studio.extend({
id: '@theatre/hello-world-extension',
toolbars: {
global(set, studio) {
const exampleBox = new Box('mobile')
const untapFn = prism<ToolsetConfig>(() => [
{
type: 'Switch',
value: val(exampleBox.derivation),
onChange: (value) => exampleBox.set(value),
options: [
{
value: 'mobile',
label: 'view mobile version',
svgSource: '😀',
},
{
value: 'desktop',
label: 'view desktop version',
svgSource: '🪢',
},
],
},
{
type: 'Icon',
title: 'Example Icon',
svgSource: '👁‍🗨',
onClick: () => {
console.log('hello')
},
},
])
// listen to changes to this derivation using the requestAnimationFrame shared ticker
.tapImmediate(Ticker.raf, (value) => {
set(value)
})
return untapFn
},
},
panes: [],
})
studio.initialize()
ReactDOM.render(<App />, document.getElementById('root'))

View file

@ -0,0 +1,37 @@
import {editable as e, SheetProvider} from '@theatre/r3f'
import {Stars, TorusKnot} from '@react-three/drei'
import {getProject} from '@theatre/core'
import React from 'react'
import {Canvas} from '@react-three/fiber'
function App() {
return (
<div
onClick={() => {
// return setBgIndex((bgIndex) => (bgIndex + 1) % bgs.length)
}}
style={{
height: '100vh',
}}
>
<Canvas
dpr={[1.5, 2]}
linear
gl={{preserveDrawingBuffer: true}}
frameloop="demand"
>
<SheetProvider sheet={getProject('Space').sheet('Scene')}>
<ambientLight intensity={0.75} />
<e.group uniqueName="trefoil">
<TorusKnot scale={[1, 1, 1]} args={[1, 0.3, 128, 64]}>
<meshNormalMaterial />
</TorusKnot>
</e.group>
<Stars radius={500} depth={50} count={1000} factor={10} />
</SheetProvider>
</Canvas>
</div>
)
}
export default App

View file

@ -0,0 +1,63 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import type {ISheetObject} from '@theatre/core';
import { onChange, types, val} from '@theatre/core'
import studio from '@theatre/studio'
import extension from '@theatre/r3f/dist/extension'
const dataConfig = {
exampleProp: types.stringLiteral('yes', {
no: 'no',
yes: 'yes',
}),
}
studio.extend(extension)
studio.extend({
id: '@theatre/hello-world-extension',
toolbars: {
global(set, studio) {
// A sheet object used by this extension
const obj: ISheetObject<typeof dataConfig> = studio
.getStudioProject()
.sheet('example extension UI')
.object('editor', dataConfig)
const updateToolset = () =>
set([
{
type: 'Switch',
value: val(obj.props.exampleProp),
onChange: (value) =>
studio.transaction(({set}) => set(obj.props.exampleProp, value)),
options: [
{
value: 'no',
label: 'say no',
svgSource: '👎',
},
{
value: 'yes',
label: 'say yes',
svgSource: '👍',
},
],
},
])
const untapFn = onChange(obj.props.exampleProp, () => {
updateToolset()
})
// initial update
updateToolset()
return untapFn
},
},
panes: [],
})
studio.initialize()
ReactDOM.render(<App />, document.getElementById('root'))

View file

@ -1,46 +1,52 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import type {ToolsetConfig} from '@theatre/studio'
import studio from '@theatre/studio'
import extension from '@theatre/r3f/dist/extension'
import {Box, prism, Ticker, val} from '@theatre/dataverse'
studio.extend(extension)
studio.extend({
id: '@theatre/hello-world-extension',
toolbars: {
global(set, studio) {
const exampleBox = new Box('mobile')
return prism<ToolsetConfig>(() => [
{
type: 'Switch',
value: val(exampleBox.derivation),
onChange: (value) => exampleBox.set(value),
options: [
{
value: 'mobile',
label: 'view mobile version',
svgSource: '😀',
let switchValue = 'mobile'
const updateToolset = () =>
set([
{
type: 'Switch',
value: switchValue,
onChange: (value) => {
switchValue = value
updateToolset()
},
{
value: 'desktop',
label: 'view desktop version',
svgSource: '🪢',
},
],
},
{
type: 'Icon',
title: 'Example Icon',
svgSource: '👁‍🗨',
onClick: () => {
console.log('hello')
options: [
{
value: 'mobile',
label: 'view mobile version',
svgSource: '😀',
},
{
value: 'desktop',
label: 'view desktop version',
svgSource: '🪢',
},
],
},
},
]).tapImmediate(Ticker.raf, (value) => {
set(value)
})
{
type: 'Icon',
title: 'Example Icon',
svgSource: '👁‍🗨',
onClick: () => {
console.log('hello')
},
},
])
updateToolset()
return () => {
// remove any listeners if necessary when the extension is unloaded
}
},
},
panes: [],