在使用 THREE.js 开发 3D Web 应用时,将可编辑文本集成到 3D 场景中是一项具有挑战性的任务。传统的富文本编辑器依赖 HTML 和 CSS 来渲染内容,而这与 WebGL 渲染流程不兼容。为了解决这个问题,我们构建了一个 WebGL 原生的富文本编辑器,结合了 TinyMCE 的编辑能力与 THREE.js 的 3D 渲染能力,借助 @mlightcad/mtext-renderer 库完成文本渲染工作。
为什么要基于 WebGL 的文本编辑器?
大多数 Web 富文本编辑器依赖于 DOM 渲染机制,这在传统文档中很好用,但在 3D 场景中就行不通了。我们的解决方案:
- 使用 THREE.js 将文本作为几何体在 WebGL 场景中渲染
- 支持丰富的文本样式,包括加粗、斜体、下划线、列表等
- 支持将编辑内容转换为 CAD 使用的 MText 格式,便于集成和导出
系统架构
我们的编辑器整合了以下核心技术:
- TinyMCE:功能强大的富文本编辑器,负责文字输入与格式化。
- AutoCAD MText:一种结构化的文本格式,广泛用于 CAD 场景中的复杂文本表示。
- @mlightcad/mtext-renderer:一个基于 THREE.js 的渲染器,用于在 3D 场景中渲染 MText 文本。
这种架构使用户可以在熟悉的界面中编辑文本,并将其实时呈现在 3D WebGL 场景中。
主要功能
WebGL 原生文本渲染
所有文本内容都被转化为几何体并由 WebGL 渲染,完全不依赖 HTML/CSS。
使用 TinyMCE 提供完整的格式支持
支持以下富文本样式:
- 字体样式:字体、字号、加粗、斜体、下划线、上划线、删除线
- 高级排版:下标、上标、分数
- 字符控制:字间距、字宽
- 对齐方式:左对齐、居中、右对齐、两端对齐
- 列表:项目符号和编号列表
实时场景更新
用户在 TinyMCE 中编辑的内容会实时同步到 3D 场景中,无需手动刷新。
支持 AutoCAD MText 格式
所有格式化文本会被转换为 AutoCAD 使用的 MText 格式,便于在 CAD 工作流程中使用。
字体加载与缓存机制
通过 IndexedDB 本地缓存字体数据,提高加载速度,支持缺字替代和默认字体降级处理。
从 TinyMCE 到 AutoCAD MText 的转换
为了在 THREE.js 中渲染富文本内容,我们需要将 TinyMCE 的内容模型转换为 AutoCAD 的 MText 字符串。
转换流程
转换过程分为两个主要步骤:
-
解析 TinyMCE 的数据模型:
TinyMCE 使用树状结构描述内容和样式。转换器会遍历每个节点,提取如加粗、字体、颜色、字号、间距等样式信息。
-
生成 MText 格式指令:
提取到的样式被转换为 MText 指令,例如:
\f
表示字体(如:\fArial|b1|i0;
)\C
和\c
表示颜色(ACI 颜色和 RGB 颜色)\H
、\W
、\T
表示字号、字宽、字距\L
、\O
、\K
表示下划线、上划线、删除线\S
用于上标、下标和分数\P
表示段落换行,\px...;
表示段落格式属性
若节点具有样式,转换器会用 {}
将其包装,从而支持嵌套样式与局部格式控制。
在线演示
您可以通过以下链接在线体验该编辑器:
MText 渲染器架构概览
@mlightcad/mtext-renderer
是一个模块化的 MText 渲染库,核心组件包括:
- FontManager:管理字体加载、缓存和字符轮廓提取。
- FontLoader:从 JSON 或自定义源加载字体信息。
- FontCacheManager:通过 IndexedDB 缓存字体数据。
- FontFactory:根据字体类型(SHX 或网格字体)创建实例。
- BaseFont / BaseTextShape:字体与字符图形的抽象基类。
- MText:主类,用于组织和渲染富文本块。
类结构图(简化版)
classDiagram
MText --> FontManager
MText --> StyleManager
FontManager --> FontFactory
FontManager --> FontCacheManager
FontManager --> BaseFont
DefaultFontLoader ..|> FontLoader
BaseFont <|-- MeshFont
BaseFont <|-- ShxFont
BaseTextShape <|-- MeshTextShape
BaseTextShape <|-- ShxTextShape
使用示例
import * as THREE from 'three';
import { DefaultFontLoader, FontManager, MText, StyleManager } from '@mlightcad/mtext-renderer';
const fontManager = FontManager.instance;
const styleManager = new StyleManager();
const fontLoader = new DefaultFontLoader();
await fontLoader.load(['simsun']); // 加载字体
const content = {
text: '{\fArial|b0|i0|c0|p34;Hello World}',
height: 0.1,
width: 0,
position: new THREE.Vector3(0, 0, 0),
};
const style = {
name: 'Standard',
fixedTextHeight: 0.1,
widthFactor: 1,
font: 'Standard',
color: 0xffffff,
obliqueAngle: 0,
textGenerationFlag: 0,
lastHeight: 0.1,
bigFont: '',
standardFlag: 0,
};
const mtext = new MText(content, style, styleManager, fontManager);
scene.add(mtext);
应用场景
- 3D 标注工具
- 技术文档可视化
- CAD 阅读器中的文本编辑功能
- 教育类三维内容展示
- 富文本 UI 控件
总结
这款基于 WebGL 的富文本编辑器,将传统 WYSIWYG 编辑体验扩展到 3D 场景中。通过结合 TinyMCE 编辑器、AutoCAD 的 MText 格式以及基于 THREE.js 的渲染器,开发者可以在 WebGL 中实现复杂的文本排版与渲染,满足技术、设计、教育等多种场景的需求。
无论是构建 CAD 浏览器、教育仿真平台还是创意设计工具,本项目都能让用户在 3D 空间中自由编辑并展现高保真富文本内容。