基于 Vue3 与 Three.js 构建工业级 3D 场景编辑器
介绍基于 Vue3、Vite、Three.js 和 Element Plus 构建工业级 Web 3D 场景编辑器的技术方案。内容涵盖模型导入、实时变换控制、场景大纲树、材质编辑及导出功能。详细解析了 Three.js 渲染架构、TransformControls 交互系统、Canvas 水印保护机制及性能优化策略。项目采用暗色主题设计,支持快捷键操作,适用于智慧工地、数字孪生等可视化场景。

介绍基于 Vue3、Vite、Three.js 和 Element Plus 构建工业级 Web 3D 场景编辑器的技术方案。内容涵盖模型导入、实时变换控制、场景大纲树、材质编辑及导出功能。详细解析了 Three.js 渲染架构、TransformControls 交互系统、Canvas 水印保护机制及性能优化策略。项目采用暗色主题设计,支持快捷键操作,适用于智慧工地、数字孪生等可视化场景。

![3D 场景编辑器界面]
在智慧工地、数字孪生、工业仿真等领域,3D 场景编辑器是核心底座工具。本文将带你从零实现一个功能完整的 Web 3D 编辑器,支持模型导入、实时变换、材质编辑、场景导出等专业功能。
项目技术栈:
适合人群:前端工程师、3D 可视化开发者、数字孪生从业者
// 场景初始化核心代码片段
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(50, aspect, 0.1, 2000)
renderer = new THREE.WebGLRenderer({antialias:true,alpha:true})
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 1.2
renderer.shadowMap.enabled = true
实现拖拽式对象变换,支持三种模式(translate/rotate/scale):
const transformControls = new TransformControls(camera, renderer.domElement)
transformControls.addEventListener('dragging-changed',(event)=>{
orbitControls.enabled = !event.value // 拖拽时禁用相机
})
transformControls.setMode('translate')// 切换工具模式
![3D 场景编辑器界面]
Model3DEditor (主容器)
├── EditorHeader (顶部工具栏)
├── ModelLibrary (左侧模型库)
├── Viewport (中央渲染视口)
│ ├── TransformControls (变换控制器)
│ ├── OrbitControls (相机控制)
│ └── GridHelper (网格辅助)
├── OutlinerPanel (场景大纲)
└── PropertiesPanel (属性面板)
使用 ref + emit 实现父子组件通信:
// 选中对象状态管理
const selectedModelId = ref(null)
const selectedModel = computed(()=> placedModels.value.find(m=> m.id === selectedModelId.value))
// 子组件触发选中事件
emit('select', modelId)
支持拖拽导入 GLB/GLTF 文件,使用 GLTFLoader:
import{ GLTFLoader }from'three/examples/jsm/loaders/GLTFLoader.js'
const loader = new GLTFLoader()
loader.load(url,(gltf)=>{
const model = gltf.scene
model.traverse(child=>{
if(child.isMesh){ child.castShadow =true child.receiveShadow =true}
})
scene.add(model)
})
![3D 场景编辑器界面]
实现层级展示与批量操作:
<template>
<div v-for="model in models" :key="model.id">
<el-checkbox @change="handleSelect(model.id, $event)" />
<el-icon @click="toggleVisibility(model.id)"> {{ model.visible ? 'View' : 'Hide' }} </el-icon>
<span>{{ model.label }}</span>
</div>
</template>
支持功能:
使用 Canvas 绘制防盗用水印:
function drawWatermark(){
const canvas = watermarkCanvas.value
const ctx = canvas.getContext('2d')
ctx.font ='14px Arial'
ctx.fillStyle ='rgba(150, 150, 150, 0.15)'
ctx.rotate(-20* Math.PI/180)
const text ='© 2025'
const gap =180
for(let y =-canvas.height; y < canvas.height *2; y += gap){
for(let x =-canvas.width; x < canvas.width *2; x += gap){
ctx.fillText(text, x, y)
}
}
}
![3D 场景编辑器界面]
npm run dev # 访问 http://localhost:2288
npm run build
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Three.js | 生态成熟、学习成本低 | 需手动管理渲染循环 | Web 端轻量级 3D |
| Babylon.js | 集成度高、内置编辑器 | 包体积较大 | 游戏开发 |
| Unity WebGL | 功能最强大 | 初始加载慢 | 重度 3D 应用 |
本项目选择 Three.js 的原因:
参考专业 3D 软件(Blender/Maya)风格:
:root{
--bg: #1e1e2e;
--bg-panel: #252536;
--accent: #6366f1;
--text: #e2e8f0;
}
内置快捷键面板(按 H 唤起):
W/E/R - 切换变换工具Del - 删除选中对象F - 聚焦选中对象Ctrl+D - 复制对象![3D 场景编辑器界面]
// 视锥剔除
renderer.setPixelRatio(Math.min(window.devicePixelRatio,2))
// 按需渲染(无交互时停止刷新)
let needsRender =true
function animate(){
if(needsRender){
renderer.render(scene, camera)
needsRender =false
}
requestAnimationFrame(animate)
}
transformControls.addEventListener('change',()=>{
needsRender =true
})
本文从架构设计到核心实现,详细讲解了如何构建一个工业级 Web 3D 编辑器。项目代码已开源,可直接用于:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online