资源推荐
UIKit:在 Three.js 中构建 3D UI

还在用DOM叠加做3D交互?这个工具让你直接在Three.js里写UI

想做一个酷炫的3D产品展示页,或者给游戏加个交互界面,结果发现在Three.js场景里加个按钮都要算半天坐标?

传统方案要么用DOM叠加在Canvas上——性能差还无法真正融入3D空间;要么纯Three.js硬写——手动创建mesh、处理点击检测、计算每个元素的位置,改个间距就得重新算一遍坐标。

今天给大家介绍一个工具——UIKit,让你用Flexbox布局3D界面,用React组件写UI交互,就像开发普通网页一样自然。

UIKit是什么?一句话说清楚

简单来说,UIKit是一个让你在Three.js里用Flexbox和React组件开发3D UI的库

它基于三个核心技术:

  • Three.js:业界标准的3D渲染引擎
  • React Three Fiber:Three.js的React声明式封装
  • Yoga引擎:Facebook开源的跨平台Flexbox布局引擎

由Poimandres团队维护(就是React Three Fiber生态的核心开发团队),代码质量和持续性都有保障。

传统方案 vs UIKit

传统方案的痛点UIKit的解决方式
❌ 手动计算坐标位置✅ Flexbox自动布局
❌ DOM叠加性能差✅ 真3D渲染,性能原生
❌ 事件处理复杂✅ React式事件系统
❌ 响应式布局困难✅ 内置断点系统(sm/md/lg)

UIKit解决的核心问题是:把前端开发者熟悉的UI开发方式,带入3D空间


为什么推荐给前端开发者?

Flexbox布局:用CSS思维组织3D空间

以前在Three.js里布局UI元素,要手动设置每个对象的positionrotationscale,一堆数字很难维护。改个间距或对齐方式,就得重新计算所有坐标。

现在用UIKit,直接写:

<Container
  flexDirection="row"
  gap={20}
  justifyContent="center"
>

就像写CSS Flexbox一样,gap控制间距,justifyContent控制对齐,所有布局引擎自动计算。你的React布局经验可以直接迁移到3D场景,零学习成本。

组件化开发:预设UI库开箱即用

从零实现一个3D按钮需要什么?创建mesh、添加材质、处理点击检测、实现hover状态、加上文字渲染...至少几十行代码。

UIKit提供了预设组件:

<Button onClick={handleClick}>点击我</Button>
<Input value={text} onChange={setText} />
<Container> {/* 类似div */}

开箱即用,还支持两套设计系统:

  • default-kit:基于Shadcn的现代风格
  • horizon-kit:Meta Horizon的VR风格

想自定义样式?所有组件都支持主题定制和材质替换。

响应式设计:3D界面也能适配屏幕

做跨平台3D应用最头疼的是什么?VR头显、PC显示器、手机屏幕尺寸差距巨大,传统方案要写三套UI逻辑。

UIKit内置断点系统:

<Container
  sm={{ width: 100, flexDirection: 'column' }}
  lg={{ width: 200, flexDirection: 'row' }}
>

和CSS媒体查询一样的思路,一套代码多端适配。smmdlgxl2xl五个断点,覆盖从手机到大屏的所有场景。

交互状态:hover/active就像写CSS伪类

以前实现hover效果要监听射线检测事件,手动管理悬停状态,更新材质颜色...光是一个按钮的hover就要写几十行代码。

现在只需要:

<Button
  backgroundColor="blue"
  hover={{ backgroundColor: 'lightblue', scale: 1.1 }}
  active={{ scale: 0.95 }}
>

就像CSS的:hover:active伪类,所有交互逻辑UIKit自动处理。还支持focus状态和暗色模式适配。

性能更好:UI再多也不掉帧

传统React Three Fiber应用,状态更新会触发组件重渲染,复杂UI容易掉帧。

UIKit用了一套更聪明的更新机制,属性变化时直接改Three.js对象,不走React的渲染流程。实际效果是:即使有上百个UI元素同时更新动画,也能稳定保持60fps。

5分钟上手:一个3D空间里的卡片布局

安装依赖

npm install three @react-three/fiber @react-three/uikit

写一个简单的3D卡片

import { Canvas } from '@react-three/fiber'
import { Container, Text } from '@react-three/uikit'
 
function Card() {
  return (
    <Container
      flexDirection="column"
      padding={20}
      gap={10}
      backgroundColor="white"
      borderRadius={8}
      hover={{ scale: 1.05 }}
    >
      <Text fontSize={24}>Hello 3D UI</Text>
      <Text fontSize={16} opacity={0.7}>
        这是用Flexbox布局的3D卡片
      </Text>
    </Container>
  )
}
 
export default function App() {
  return (
    <Canvas>
      <Card />
    </Canvas>
  )
}

代码解读

  • Container:类似HTML的div,支持Flexbox所有属性
  • flexDirection/gap/padding:和CSS完全一致的API,不用记新的
  • backgroundColor/borderRadius:直接用熟悉的样式属性,自动转换成3D材质
  • hover={{ scale: 1.05 }}:鼠标悬停时放大5%,交互效果一行搞定

运行后你会看到一张浮动在3D空间中的卡片,可以用鼠标拖拽旋转场景查看不同角度。支持所有React Three Fiber的事件:onClickonPointerEnteronPointerLeave等,就像写普通React组件一样。


哪些场景适合用?

游戏UI

背包系统、技能树、血条,这些游戏UI传统方案是DOM叠加,但容易闪烁、不同步。纯Three.js手写的话,一个可拖拽的背包面板就要几百行代码。

UIKit让UI真正融入3D场景,事件系统原生支持手柄和触摸。性能上,复杂UI的帧率比DOM方案高一个数量级。

VR/AR应用

VR环境里传统DOM完全没法用。手写Three.js实现设置面板,要处理射线检测、手柄交互、凝视触发,工作量巨大。

UIKit内置了WebXR支持和交互逻辑,响应式系统能适配不同头显分辨率,一套代码多端通用。

3D产品展示

电商看货、汽车配置器需要在模型旁边放参数面板。DOM叠加的方案,UI和模型分离,很难让按钮跟随模型旋转。

UIKit的UI在Three.js场景里,可以锚定到模型任何部位。比如在车门上放个按钮,无论怎么旋转视角都能精确跟随。


写在最后

UIKit让3D UI开发回归到前端熟悉的领域。Flexbox、React组件、响应式断点,这些平时写Web用的技能,直接拿来写3D场景里的界面。

不用重新学3D坐标系和矩阵运算,用现有技能就能做出真正融入场景的3D UI。对想尝试3D开发的前端来说,这可能是最顺滑的起点。

相关链接: