这是一个系列博客,最终目的是要做一个基于 HTML Canvas 的、类似于微软 Office 的 Web Office 套件(包括:文档、表格、幻灯片……等等)。 博客园:《从零开始, 开发一个 Web Office 套件》系列博客目录 富文本编辑器 Github repo 地址:https://github.com/zhaokang555/canvas-text-editor
2. 富文本编辑器(MVP)
2.18 Click 事件的 z-index
2.18.1 新的问题:点击空白处
首先,我们先观察一下其他的幻灯片软件:
通过上图可以发现,当我们点击编辑器内空白处时,编辑器会执行以下逻辑:
- 找到距离点击位置最近的行
- 在此行内找到距离点击位置最近的字符
- 在此字符的左侧或者右侧插入光标
为了实现这个feature,我们就要监听编辑器空白处的click事件。与此同时,我们会遇到和hover事件相同的问题: 我们需要找到最上层的元素(Char or 空白),触发它的点击事件。
2.18.2 重构
修改ClickZone
,在handle canvas click时不直接触发onClick
,而是根据zIndex将onClick
记录到topLayerCallbacks
中:
然后,在CanvasTextEditor.render()
中触发回调函数,之后清空topLayerCallbacks
:
同时,修改CanvasTextEditorChar.constructor()
的实现,传入zIndex:
这样,ClickZone
就支持了z-index.
2.19 Feature: 点击编辑器空白处后,在适当位置插入光标
修改CanvasTextEditor
, 添加blankSpace
属性, 大小和整个编辑器重叠:
然后,添加handleClickOnTheBlankSpace
方法,实现文章开头所描述的算法:
其中,形参mouseX
和mouseY
代表点击位置,我们需要修改ClickZone
将其传入:
效果:
2.19.1 Fix bug
不过,细心的读者会发现一个问题:当我们点击最左侧区域,试图在第二行第一个字符前插入光标,结果光标跑到了第一行末尾。
这是因为,我们之前将行首的char的prev属性赋值成了上一行行尾的char。要解决这个bug,只需要将赋值相关代码从Paragraph
中挪到SoftLine
中:
效果:
2.19.2 Fix: 光标在不同位置粗细不一
细心观察上图的同学会发现一个样式问题:光标在不同位置时,其粗细肉眼可见地不一致。这是因为根据字符位置,计算出来的光标的位置不是整数。我们只需要将其坐标取整就可以了:
效果:
(未完待续)