Skip to content

252. 实战:3D 画廊编辑器(三)

Published:

这节正式开始画廊编辑器的开发。

这节我们把布局写一下。

image.png

可以分为 Header、Menu、Main 这三个组件。

创建项目:

npx create-vite gallery-editor

image.png

选择 react、typescript

进入项目,安装依赖和 three.js:

pnpm install
pnpm install --save three
pnpm 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';

function App() {
  return <div className='wrap'>
    <Header />
    <div className='editor'>
      <Menu/>
      <Main/>
    </div>
  </div>
}

export default App

按照之前分析的结构,拆分 Header、Main、Menu 这三个组件,放在 components 目录下。

安装下 sass

pnpm 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;

然后在 main.tsx 里去掉 index.css 和 StrictMode

image.png

跑一下:

npm run dev

image.png

image.png

然后来写下布局

image.png

.wrap {
  height: 100vh;
  display: flex;
  flex-direction: column;

  .Header {
    height: 60px;
    border-bottom: 1px solid #000;
  }

  .editor {
    flex: 1;
  }
}

竖直方向 flex 布局。

整体是 100vh,上面 60px 下面 flex 1

看下效果:

image.png

然后写下下面部分的布局:

image.png

和之前的酷家乐编辑器一样,下面的 Main 是占整个屏幕宽度。

左边的 Menu 绝对定位,可以展开收起。

image.png

.editor {
    flex: 1;

    position: relative;

    .Menu {
      position: absolute;
      top: 0;
      width: 200px;
      height: calc(100vh - 60px);
      background: pink;
    }
    .Menu {
      left: 0;
      border-right: 1px solid #000;
    }
}

中间占据 100% 宽度,左侧是固定宽度绝对定位的面板。

image.png

这样,布局就完成了。

然后加一下展开收起的按钮:

写个 div:

image.png

<div className="drawer-bar"></div>

写下样式:

image.png

.drawer-bar {
  width: 10px;
  height: 80px;
  background: black;
  position: absolute;
  right: -10px;
  top: 50%;
  transform: translateY(-50%);
  cursor:pointer;
}

绝对定位,固定宽高。

看下效果:

image.png

点击的时候,改下 left

image.png

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 ? -200 : 0);
        }}></div>
    </div>
}

export default Menu;

用 state 保存 left,点击的时候修改 left 为 0 或 -200

2025-10-19 20.18.47.gif

给 left 加个过渡效果:

image.png

transition: left 0.5s ease-in-out;

缓动的动画,0.5s

试一下:

2025-10-19 20.20.59.gif

平滑多了。

这样,布局就完成了。

案例代码上传了小册仓库

总结

这节我们实现了布局。

上面固定 60px,下面是 Main 占据整个宽度,左边 Menu 面板绝对定位,固定宽度。

并且 Menu 还可以点击按钮展开收起,通过修改 left,并且我们还加了一个过渡效果。

布局写完了,下节来写 threejs 部分。

评论