three.cad/src/app.jsx

161 lines
3.9 KiB
React
Raw Normal View History

2021-03-26 17:25:28 +08:00
2021-04-02 16:04:42 +08:00
import React, { useEffect, useReducer, useRef, useState } from 'react';
2021-04-01 16:20:50 +08:00
import './app.css'
2021-03-26 17:25:28 +08:00
2021-03-28 20:00:31 +08:00
import { Provider, useDispatch, useSelector } from 'react-redux'
2021-04-02 16:04:42 +08:00
import { FaCube, FaEdit } from 'react-icons/fa'
import { MdEdit, MdDone, MdVisibilityOff, MdVisibility } from 'react-icons/md'
import { RiShape2Fill } from 'react-icons/ri'
import { Union, Subtract, Intersect, Line, Arc } from './icons'
import { color } from './utils/static'
2021-03-28 20:00:31 +08:00
2021-03-27 03:18:11 +08:00
export const Root = ({ store }) => (
2021-03-26 17:25:28 +08:00
<Provider store={store}>
2021-03-27 03:18:11 +08:00
<App></App>
2021-03-26 17:25:28 +08:00
</Provider>
);
2021-03-27 03:18:11 +08:00
2021-03-30 13:13:13 +08:00
2021-03-27 03:18:11 +08:00
const App = () => {
2021-03-28 20:00:31 +08:00
const dispatch = useDispatch()
2021-03-29 18:27:34 +08:00
const treeEntries = useSelector(state => state.treeEntries)
2021-04-01 13:35:08 +08:00
const activeSketchNid = useSelector(state => state.activeSketchNid)
2021-03-30 13:13:13 +08:00
// const [state, setState] = useState('x')
// useEffect(()=>{
// console.log('hereeee')
// },[state])
2021-04-02 16:04:42 +08:00
2021-03-30 13:13:13 +08:00
useEffect(() => {
2021-04-01 13:35:08 +08:00
if (!activeSketchNid) {
2021-03-31 07:20:24 +08:00
sc.canvas.addEventListener('pointermove', sc.onHover)
sc.canvas.addEventListener('pointerdown', sc.onPick)
2021-04-01 16:20:50 +08:00
return () => {
sc.canvas.removeEventListener('pointermove', sc.onHover)
sc.canvas.removeEventListener('pointerdown', sc.onPick)
2021-03-31 07:20:24 +08:00
}
2021-03-30 13:13:13 +08:00
}
2021-04-01 13:35:08 +08:00
}, [activeSketchNid])
2021-03-27 03:18:11 +08:00
2021-03-28 20:00:31 +08:00
2021-04-02 08:19:14 +08:00
const btnz = [
activeSketchNid ?
[MdDone, () => treeEntries.byNid[activeSketchNid].deactivate(), 'Finish'] :
2021-04-02 16:04:42 +08:00
[FaEdit, sc.addSketch, 'Sketch']
2021-04-02 08:19:14 +08:00
,
2021-04-02 16:04:42 +08:00
[FaCube, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Extrude'],
[Union, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Union'],
[Subtract, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Subtract'],
[Intersect, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Intersect'],
[Line, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Line'],
[Arc, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Arc'],
2021-04-02 08:19:14 +08:00
]
2021-04-01 18:10:00 +08:00
2021-04-02 08:19:14 +08:00
return <div className='absolute left-0 w-1/6 flex flex-col'>
{
2021-04-02 16:04:42 +08:00
btnz.map(([Icon, fcn, txt], idx) => (
<div className="btn flex items-center justify-end p-1 text-lg w-36" key={idx}
2021-04-02 08:19:14 +08:00
onClick={fcn}
2021-04-01 16:20:50 +08:00
>
2021-04-02 08:19:14 +08:00
<div>{txt}</div>
2021-04-02 16:04:42 +08:00
<Icon className="w-6 h-6 ml-1" />
2021-04-02 08:19:14 +08:00
</div>
))
}
<div className=''>
{treeEntries.allNids.map((entId, idx) => (
2021-04-02 16:04:42 +08:00
<TreeEntry key={idx} entId={entId} />
2021-03-28 20:00:31 +08:00
))}
</div>
2021-04-02 16:04:42 +08:00
2021-04-02 08:19:14 +08:00
</div>
2021-04-02 16:04:42 +08:00
2021-03-28 20:00:31 +08:00
}
2021-04-02 16:04:42 +08:00
const TreeEntry = ({ entId }) => {
const treeEntries = useSelector(state => state.treeEntries.byNid)
const activeSketchNid = useSelector(state => state.activeSketchNid)
let entry;
if (entId[0]=="s") {
entry = treeEntries[entId].obj3d
} else {
entry = treeEntries[entId]
}
const [_, forceUpdate] = useReducer(x => x + 1, 0);
const vis = entry.visible
return <div className='bg-gray-50 flex justify-between'>
<div className='btn'
onClick={() => {
activeSketchNid && treeEntries[activeSketchNid].deactivate()
entry.activate()
}}
>
<MdEdit />
</div>
{
vis ?
<div className='btn'
onClick={() => {
entry.visible = false;
sc.render()
forceUpdate()
}}
>
<MdVisibility />
</div>
:
<div className='btn'
onClick={() => {
entry.visible = true;
sc.render()
forceUpdate()
}}
>
<MdVisibilityOff />
</div>
}
<div className="btn"
onPointerEnter={() => {
if (entId[0] == 'm') {
entry.material.color.set(color.hover)
sc.render()
}
}}
onPointerLeave={() => {
const obj = entry
if (entId[0] == 'm' && !sc.selected.includes(obj)) {
obj.material.color.set(color.m)
sc.render()
}
}}
onPointerDown={() => {
if (entId[0] == 'm') {
sc.selected.push(
entry
)
sc.render()
}
}}
>
{entId}
</div>
</div>
}
const DesignLeaf = () => {
}