从零开始, 开发一个 Web Office 套件 (1): 富文本编辑器

这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office 套件, 包括: 文档, 表格, 幻灯片... 等等.

文本编辑器

万里长征的第一步: 我们先开发一个基于canvas的富文本编辑器. 之后, 这个编辑器可以用在我们所有类型的文档中(文档, 表格, 幻灯片...).
对应的Github repo 地址: https://github.com/zhaokang555/canvas-text-editor

1. Environment setup

工欲善其事, 必先利其器. 首先我们来配置项目环境

1.1 初步构想

我们的富文本编辑器项目包含两大部分:

编辑器本体

可以单独打包发布到npm上

暂定使用TypeScript开发

demo

若干纯静态网页, 用于展示编辑器的功能

暂定使用React + TypeScript开发

1.2 Vite

我们使用Vite (https://cn.vitejs.dev/)作为我们的打包工具.
为什么使用Vite, 而不是Webpack呢? 可以看这里: https://cn.vitejs.dev/guide/why.html

1.3 使用Vite初始化项目

image

1.4 调整项目目录结构

我们新建2个文件夹:

src/demo:

用于存放所有的demo页

将原先src目录下的所有文件挪到这里

src/core: 用于存放编辑器本体

1.5 Hello, world!

在src/core目录下, 新建一个文件: CanvasTextEditor.ts. 写上最简单的代码, 在canvas上渲染出一行Hello, world!:

image

修改src/demo/App.tsx, 初始化CanvasTextEditor:

image

添加SASS依赖, 并重置浏览器重置样式

image

添加文件 src/demo/main.scss

image

修改文件 src/demo/main.tsx, 引入main.scss

image

效果:

image

2. 富文本编辑器(MVP) 2.1 计算文字包围盒

首先, 我们要找到一种方法, 来确定任意一段文字的包围盒. 为什么要确定包围盒呢? 因为:

当我们的鼠标hover在文字上方的时候, 需要产生相应的样式变化. 在DOM中, 这个功能是浏览器帮我们实现的. 但是现在在canvas中, 因为整个canvas对于浏览器来说, 就是一个栅格图像, 所以我们需要自己计算, 实现这个功能.

当我们在文字上方点击的时候, 需要在对应位置插入闪烁的光标.

CanvasRenderingContext2D 提供了 measureText API, 可以帮我们度量文字尺寸:

https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/measureText

https://developer.mozilla.org/zh-CN/docs/Web/API/TextMetrics

接下来, 我们来看一下这个API都返回了哪些有用的信息.

修改src/core/CanvasTextEditor.ts, 将measureText接口返回结果打印出来:

image

image

问题来了, fontBoundingBox和actualBoundingBox的区别是什么呢? MDN是这样描述的:

actualBoundingBox: 渲染文本的矩形边界

fontBoundingBox: 渲染文本的所有字体的矩形边界

看完文档, 还是不确定哪一个使我们想要的. 所以, 我们来给canvas上添加一些辅助线, 来帮助我们更形象地对比下两者的区别. 我们用红色画出actualBoundingBox, 用绿色画出fontBoundingBox:

从零开始, 开发一个 Web Office 套件 (1): 富文本编辑器

注意, 为了方便计算, 我们将textBaseLine设置为top. 如果有小伙伴不熟悉textBaseLine, 可以看MDN提供的这张图:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzzsx.html