feat(example): three-basic (#418)
This commit is contained in:
parent
4c375672af
commit
e7f23cfa4e
5 changed files with 382 additions and 0 deletions
79
packages/playground/src/shared/dom-basic/Box3D.tsx
Normal file
79
packages/playground/src/shared/dom-basic/Box3D.tsx
Normal file
|
@ -0,0 +1,79 @@
|
|||
import React, {useEffect, useRef} from 'react'
|
||||
import type {CSSProperties} from 'react'
|
||||
import {types} from '@theatre/core'
|
||||
import type {ISheet} from '@theatre/core'
|
||||
|
||||
// Box element
|
||||
export const BoxSize = 100
|
||||
|
||||
const Box3DCSS: CSSProperties = {
|
||||
border: '1px solid #999',
|
||||
position: 'absolute',
|
||||
width: `${BoxSize}px`,
|
||||
height: `${BoxSize}px`,
|
||||
}
|
||||
|
||||
const Box3DTextCSS: CSSProperties = {
|
||||
margin: '0',
|
||||
padding: '0',
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
top: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
textAlign: 'center',
|
||||
width: '100%',
|
||||
}
|
||||
|
||||
export const Box3D: React.FC<{
|
||||
sheet: ISheet
|
||||
name: string
|
||||
x: number
|
||||
y: number
|
||||
}> = ({sheet, name, x, y}) => {
|
||||
const elementRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
// Animation
|
||||
useEffect(() => {
|
||||
const element = elementRef.current!
|
||||
const sheetObj = sheet.object(`Box - ${name}`, {
|
||||
background: types.rgba({r: 16 / 255, g: 16 / 255, b: 16 / 255, a: 1}),
|
||||
opacity: types.number(1, {range: [0, 1]}),
|
||||
position: {
|
||||
x: x,
|
||||
y: y,
|
||||
z: 0,
|
||||
},
|
||||
rotation: {
|
||||
x: types.number(0, {range: [-360, 360]}),
|
||||
y: types.number(0, {range: [-360, 360]}),
|
||||
z: types.number(0, {range: [-360, 360]}),
|
||||
},
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1,
|
||||
},
|
||||
})
|
||||
const unsubscribe = sheetObj.onValuesChange((values: any) => {
|
||||
const {background, opacity, position, rotation, scale} = values
|
||||
element.style.backgroundColor = `rgba(${background.r * 255}, ${
|
||||
background.g * 255
|
||||
}, ${background.b * 255}, 1)`
|
||||
element.style.opacity = opacity
|
||||
const translate3D = `translate3d(${position.x}px, ${position.y}px, ${position.z}px)`
|
||||
const rotate3D = `rotateX(${rotation.x}deg) rotateY(${rotation.y}deg) rotateZ(${rotation.z}deg)`
|
||||
const scale3D = `scaleX(${scale.x}) scaleY(${scale.y}) scaleZ(${scale.z})`
|
||||
const transform = `${scale3D} ${translate3D} ${rotate3D}`
|
||||
element.style.transform = transform
|
||||
})
|
||||
return () => {
|
||||
unsubscribe()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div ref={elementRef} style={Box3DCSS}>
|
||||
<span style={Box3DTextCSS}>{name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
53
packages/playground/src/shared/dom-basic/Scene.tsx
Normal file
53
packages/playground/src/shared/dom-basic/Scene.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import React, {useEffect, useRef} from 'react'
|
||||
import type {CSSProperties} from 'react'
|
||||
import {types} from '@theatre/core'
|
||||
import type {IProject} from '@theatre/core'
|
||||
import {Box3D, BoxSize} from './Box3D'
|
||||
|
||||
// Scene
|
||||
|
||||
const SceneCSS: CSSProperties = {
|
||||
overflow: 'hidden',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
right: '0',
|
||||
top: '0',
|
||||
bottom: '0',
|
||||
}
|
||||
|
||||
export const Scene: React.FC<{project: IProject}> = ({project}) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null!)
|
||||
const sheet = project.sheet('DOM')
|
||||
|
||||
useEffect(() => {
|
||||
const container = containerRef.current!
|
||||
const sheetObj = sheet.object('Container', {
|
||||
perspective: types.number(
|
||||
Math.max(window.innerWidth, window.innerHeight),
|
||||
{range: [0, 2000]},
|
||||
),
|
||||
originX: types.number(50, {range: [0, 100]}),
|
||||
originY: types.number(50, {range: [0, 100]}),
|
||||
})
|
||||
const unsubscribe = sheetObj.onValuesChange((values: any) => {
|
||||
container.style.perspective = `${values.perspective}px`
|
||||
container.style.perspectiveOrigin = `${values.originX}% ${values.originY}%`
|
||||
})
|
||||
return () => {
|
||||
unsubscribe()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const padding = 100
|
||||
const right = window.innerWidth - padding - BoxSize
|
||||
const bottom = window.innerHeight - padding - BoxSize
|
||||
|
||||
return (
|
||||
<div ref={containerRef} style={SceneCSS}>
|
||||
<Box3D sheet={sheet} name="Top Left" x={padding} y={padding} />
|
||||
<Box3D sheet={sheet} name="Top Right" x={right} y={padding} />
|
||||
<Box3D sheet={sheet} name="Bottom Left" x={padding} y={bottom} />
|
||||
<Box3D sheet={sheet} name="Bottom Right" x={right} y={bottom} />
|
||||
</div>
|
||||
)
|
||||
}
|
15
packages/playground/src/shared/dom-basic/index.tsx
Normal file
15
packages/playground/src/shared/dom-basic/index.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import studio from '@theatre/studio'
|
||||
import {getProject} from '@theatre/core'
|
||||
import {Scene} from './Scene'
|
||||
/**
|
||||
* This is a basic example of using Theatre.js for manipulating the DOM.
|
||||
*/
|
||||
|
||||
studio.initialize()
|
||||
|
||||
ReactDOM.render(
|
||||
<Scene project={getProject('Sample project')} />,
|
||||
document.getElementById('root'),
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue