乐于分享
好东西不私藏

源码分析:一款开源在线文档编辑器

源码分析:一款开源在线文档编辑器

我一直都想要做一个类似word/wps那样的,可以放在浏览器中使用的在线编辑的工具。其实office、wps、onlyoffice … 他们都提供了类似的解决方案。问题是,得需要部署服务端。我们很多时候,是想快速移植、组件化运行,有太多的依赖包袱会拖垮我们的精力。直到有一天,我偶然碰到了这个工具——canvas-editor,他的界面和操作让我眼前一亮,我感觉大有可为。并不是这上面的功能有多强大(当然,作品本身就很强大了),而是作者提供了一个实现的思路,这个比功能厉害多了。
分析一下,源码结构:

0. 整体架构流程图

分割线

1.关键阶段说明

(1)初始化阶段

入口:通过 new Editor(容器, 数据, 配置) 实例化编辑器;

配置合并:融合默认配置与用户配置,生成最终运行配置;

数据格式化:formatElementList 标准化页眉/正文/页脚等元素数据结构;

核心模块实例化:创建位置计算(Position)、绘制引擎(Draw)、选区管理(RangeManager)等核心模块,完成依赖注入。

(2)布局计算阶段

核心:由 Position 类主导,完成元素/行/页面的坐标、尺寸计算;

细分逻辑:基础位置计算:遍历行列表,计算每个元素的坐标、宽高、行偏移;

表格嵌套计算:递归计算表格内单元格的元素位置,支持垂直对齐;

浮动元素计算:单独维护浮动元素(图片/公式)的位置列表;

区域定位:区分页眉/页脚/正文区域,返回对应区域的位置列表。

(3)渲染阶段

绘制引擎(Draw)统筹渲染逻辑,分层次绘制:页面框架层:页眉(Header)、页脚(Footer)、页面边框(PageBorder);

内容渲染层:文本、LaTex 公式、块元素(视频/IFrame/表格);

交互层:选区高亮、水印、批注、自定义区域(Area)。

(4)交互响应阶段

事件监听:监听鼠标/键盘事件,解析光标位置、选区范围;

命令执行:通过 Command 类封装编辑操作(如插入公式、修改样式);

重绘触发:交互操作后触发布局重新计算 + Canvas 重绘,保证视图一致性。

2.核心模块与实现逻辑

2.1 核心模块拆解

模块名

核心文件路径

核心职责

Editor

src/editor/index.ts

编辑器入口,聚合所有模块,对外暴露 API(实例化、插件、命令执行)

Position

src/editor/core/position/Position.ts

位置计算核心,负责元素/行/页面的坐标、尺寸计算,区分页眉/页脚/表格区域

RangeManager

src/editor/core/range/RangeManager.ts

选区管理,计算光标/选区对应的段落、行信息,支撑文本选择、编辑范围界定

Draw

src/editor/core/draw/Draw.ts(隐含)

绘制引擎,统筹布局计算、Canvas 渲染、交互联动

LaTexUtils

src/editor/core/draw/particle/latex/utils/LaTexUtils.ts

公式渲染工具,解析 LaTex 语法,生成 SVG/PDF/Canvas 可渲染的公式数据

Area

src/editor/core/draw/interactive/Area.ts

自定义区域管理,支持区域级别的只读/编辑控制、背景/边框/占位符渲染

Event Handlers

src/editor/core/event/handlers/click.ts 等

交互事件解析,如光标选单词、点击选区识别等

Command

src/editor/index.ts(Command 类)

命令系统,封装所有编辑操作,统一执行/撤销逻辑

Plugin

src/editor/index.ts(Plugin 类)

插件管理器,提供 use 方法扩展编辑器功能(如 Word 导入导出)

2.2 核心模块实现逻辑

(1)Position(位置计算)

核心属性:维护 positionList(普通元素位置)、floatPositionList(浮动元素位置)、cursorPosition(光标位置);

核心方法:computePageRowPosition:核心计算逻辑,遍历行列表,计算每个元素的坐标、行偏移,支持表格嵌套递归计算;

getPositionList:根据当前激活区域(页眉/页脚/正文/表格)返回对应位置列表;

computePositionList:初始化/更新位置列表,按页面行批量计算。

(2)RangeManager(选区管理)

核心能力:解析光标/选区对应的段落范围,支持“向上/向下查找”匹配连续段落(按 listId/titleId 分组);

核心方法:getRangeParagraph,返回选区覆盖的页面-行映射关系,支撑段落级编辑操作(如批量样式修改)。

(3)LaTexUtils(公式渲染)

核心流程:解析:将 LaTex 字符串分词(tokenize)、语法解析(parse)、生成语法树;

布局:plan 方法根据公式类型(分式/根式/组合式)计算布局策略;

渲染:生成多段线(polylines),支持导出 SVG/PDF/Canvas 路径,适配缩放、最大宽高限制。

(4)Area(自定义区域)

核心能力:区域管理:维护 areaInfoMap,关联区域 ID 与元素/位置列表;

渲染控制:支持区域背景色、边框、占位符渲染;

编辑控制:区分 EDIT/READONLY/FORM 模式,控制区域编辑权限;

数据操作:支持区域值的获取、设置,批量替换区域内元素。

(5)Command(命令系统)

核心设计:封装所有编辑操作(如插入公式、导入 Word、修改字体),统一入口;

扩展能力:支持撤销/重做(记录命令执行历史)、插件扩展命令(如 docx 导入导出)。

3. 核心设计模式

3.1 面向对象:封装/继承/多态

封装:核心模块(Position/Area/LaTexUtils)将状态与逻辑封装在类内部,对外暴露最小化 API(如 compute/render/getXXX);

继承/多态:块元素基类 BaseBlock 定义通用接口(render/snapshot),VideoBlock/IFrameBlock 继承并实现各自逻辑;

位置计算区分页眉/页脚/正文,通过 getPositionList 统一返回,底层逻辑不同但接口一致。

3.2 命令模式(Command Pattern)

应用场景:所有编辑操作(如插入 LaTex 公式、导入 Word、修改文本样式)均封装为命令;

核心:解耦操作发起者(快捷键/菜单)与执行者(Draw/Position);

支持撤销/重做(记录命令执行栈);

统一操作入口,便于扩展和权限控制。

3.3 组合模式(Composite Pattern)

应用场景:元素渲染体系中,将“单个文本元素”“块元素”“表格/公式”统一抽象为 IElement 数据结构;

核心:Draw 层通过统一的 computeRowList/drawRow 方法处理不同类型元素,忽略“个体/组合”差异,简化渲染逻辑。

3.4 观察者模式(Observer Pattern)

应用场景:基于 EventBus 实现模块间通信;

核心:交互事件(如光标移动、选区变化)发布事件,渲染层监听后触发重绘;

插件通过订阅事件扩展功能,不侵入核心逻辑;

解耦事件发起者与响应者,提升模块独立性。

3.5 策略模式(Strategy Pattern)

应用场景:LaTex 公式渲染:plan 方法根据不同公式指令(\frac/\sqrt)选择不同布局计算策略;

位置计算:区分页眉/页脚/正文/表格,选择不同的位置列表获取策略;

核心:统一入口下适配不同场景,便于扩展新策略(如新增公式类型、新区域类型)。

3.6 享元模式(Flyweight Pattern)

应用场景:BaseBlock 中的 blockCache 缓存已创建的块元素实例;

核心:避免重复创建 DOM/计算资源,降低渲染性能开销。

3.7 插件模式(Plugin Pattern)

应用场景:通过 Plugin 类的 use 方法扩展编辑器能力

核心:核心逻辑与扩展逻辑解耦,官方仅提供核心包,扩展功能通过插件实现。

4. 核心特性与扩展能力

功能分类

具体能力

富文本操作

撤销/重做、字体/字号/样式(加粗/斜体/下划线)、对齐、标题、列表

元素插入

表格、图片、链接、代码块、分页符、LaTex 公式、日期选择器、自定义控件

页面排版

页眉/页脚/页码、页边距、分页、水印、批注、目录

交互能力

光标/选区控制、拖拽(文本/元素/控件)、右键菜单、自定义快捷键

导出/打印

Canvas 转图片

4.2 扩展能力

(1)插件扩展

自定义插件:通过 editor.use(插件) 扩展,支持新增命令、监听事件、自定义渲染。

(2)自定义交互

自定义快捷键:覆盖/新增快捷键映射,绑定命令执行;

自定义右键菜单:扩展右键菜单项,关联自定义命令;

事件监听:通过 EventBus 订阅编辑器生命周期事件(如光标移动、重绘完成)。

(3)渲染扩展

多底层支持:默认 Canvas 渲染,可切换至 SVG 渲染(feature/svg 分支);

PDF 扩展:基于 pdfjs 实现 PDF 绘制(feature/pdf 分支)。

5. 待优化方向

计算性能:大规模文档下的布局计算性能优化;

表格能力:表格分页、复杂表格样式(合并单元格、边框定制);


喜欢就关注我吧!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 源码分析:一款开源在线文档编辑器

评论 抢沙发

8 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮