这节开始进入酷家乐装修编辑器的开发。
首先我们写下布局:

可以分为 Header、Menu、Main、Properties 这四个组件。
创建项目:
npx create-vite home-decoration-editor

选择 react、typescript (前面一个编辑器用的 js,大的项目还是用 ts 写)
进入项目,安装依赖和 three.js:
npm install
npm install --save three
npm install --save-dev @types/three
安装 ant design 组件库:
npm install --save antd
改下 src/App.tsx
import './App.scss'
import Header from './components/Header';
import Menu from './components/Menu';
import Main from './components/Main';
import Properties from './components/Properties';
function App() {
return <div className='wrap'>
<Header />
<div className='editor'>
<Menu/>
<Main/>
<Properties/>
</div>
</div>
}
export default App
按照之前分析的结构,拆分 Header、Main、Menu、Properties 这四个组件:

放在 components 目录下。
安装下 sass
npm install --save-dev sass
改下 src/App.scss
body {
margin: 0;
}
创建四个组件:
src/components/Header/index.tsx
function Header() {
return <div className="Header">Header</div>
}
export default Header;
src/components/Main/index.tsx
function Main() {
return <div className="Main">Main</div>
}
export default Main;
src/components/Menu/index.jsx
function Menu() {
return <div className="Menu">Menu</div>
}
export default Menu;
src/components/Properties/index.jsx
function Properties() {
return <div className="Properties">Properties</div>
}
export default Properties;
然后在 main.tsx 里去掉 index.css 和 StrictMode

跑一下:
npm run dev


然后来写下布局

.wrap {
height: 100vh;
display: flex;
flex-direction: column;
.Header {
height: 60px;
border-bottom: 1px solid #000;
}
.editor {
flex: 1;
}
}
竖直方向 flex 布局。
整体是 100vh,上面 60px 下面 flex 1
看下效果:

酷家乐下面部分的布局是这样的:

画布占据了整个网页宽度,在上面绝对定位放着两侧的面板。
我们也来写一下:

.editor {
flex: 1;
position: relative;
.Menu,.Properties {
position: absolute;
top: 0;
width: 300px;
height: calc(100vh - 60px);
background: pink;
}
.Menu {
left: 0;
border-right: 1px solid #000;
}
.Properties {
right: 0;
background: orange;
border-left: 1px solid #000;
}
}
中间占据 100% 宽度,左右两侧是固定宽度绝对定位的两个面板。

这样,布局就完成了。
我们也可以加一下这个:

写个 div:


<div className="drawer-bar"></div>
写下样式:

.drawer-bar {
width: 10px;
height: 80px;
background: black;
position: absolute;
right: -10px;
top: 50%;
transform: translateY(-50%);
cursor:pointer;
}
.Properties {
.drawer-bar {
left: -10px;
}
}
绝对定位,固定宽高。
看下效果:

点击的时候,改下 left、right

import { useState } from "react";
function Properties() {
const [right, setRight] = useState(0);
return <div className="Properties" style={{right: right}}>
Properties
<div className="drawer-bar" onClick={() => {
setRight(right === 0 ? -300 : 0);
}}></div>
</div>
}
export default Properties;
用 state 保存 right,点击的时候修改 right 为 0 或 -300

给 left、right 加个过渡效果:

transition: left 0.5s ease-in-out,right 0.5s ease-in-out;
缓动的动画,0.5s
试一下:

平滑多了。
另一个组件也是同样,只不过改 left:
import { useState } from "react";
function Menu() {
const [left, setLeft] = useState(0);
return <div className="Menu" style={{left: left}}>
Menu
<div className="drawer-bar" onClick={() => {
setLeft(left === 0 ? -300 : 0);
}}></div>
</div>
}
export default Menu;

这样,布局就完成了。
和酷家乐的一样:

案例代码上传了小册仓库
总结
这节我们实现了布局。
上面固定 60px,下面是 Main 占据整个宽度,左右两个面板绝对定位,固定宽度。
并且左右两边还可以点击按钮展开收起,通过修改 left、right,并且我们还加了一个过渡效果。
布局写完了,下节来写 threejs 部分。