回到正题, 渲染结果如下:
问题来了, fontBoundingBoxDescent 多出来的那一部分究竟是什么呢? 让我们修改文字内容再试一次:
这次两个矩形基本重合了. 所以, actualBoundingBoxDescent中的actual的意思就很明显了: 实际渲染出的字符距离baseLine的最大距离. 而fontBoundingBoxDescent是不关心实际渲染字符的, 它只关心所有可用的字符.
所以, 为了一致性, 我们使用后者.
2.2 缓存(记录)文字包围盒既然找到了计算文字包围盒的方法, 接下来, 我们需要在每次绘制文字的时候, 将其缓存起来, 方便我们后续使用. 新建文件src/core/CanvasTextEditorText.ts:
修改src/core/CanvasTextEditor.ts, 使用一个数组将我们想要渲染的文字都储存起来:
2.3 根据鼠标位置, 修改鼠标样式接下来, 我们要实现的是这个功能:
当我们的鼠标hover到文字上的时候, 需要修改鼠标的样式, 类似CSS中的cursor: text;
我暂时想到了一种简单的方案: 就是当鼠标移动到某些区域的时候, 修改canvas的style, 加上cursor: text. 当鼠标移出这些区域的时候, 去掉cursor: text;
问题来了, 如何获取到鼠标在canvas中的坐标呢? 我们可以先用一种简单的方案: 监听mousemove, 并且和canvas的位置作差.
修改src/core/CanvasTextEditor.ts:
重构src/core/CanvasTextEditorText.ts:
最终效果:
2.4 文本自动折行截止到目前, 一切似乎都很正常. 但是, 当我们的文本很长的时候, 它并不会折行. 这就导致过长的文字会显示不全. 因此, 我们需要实现一个功能: 当文字触碰到canvas边缘的时候, 可以自动折行.
实现这个功能之前, 我们先对现有代码进行一下重构, 让我们可以清晰地看到canvas的边缘:
修改src/demo/main.scss, 给body一个背景色:
修改src/core/CanvasTextEditor.ts, 给canvas一个白色背景色:
重构src/core/CanvasTextEditorText.ts, 给文字设置一个黑色默认颜色:
这样, 我们可以清晰地看到, 文字后半段没有显示:
接下来, 我们来解决文字显示不全的问题. 我暂时想到了一种算法: