首页 > 技术文章 > 从零开始, 开发一个 Web Office 套件 (3): 鼠标事件

forzhaokang 2022-02-15 14:57 原文

《从零开始, 开发一个 Web Office 套件》系列博客目录
这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office 套件, 包括: 文档, 表格, 幻灯片... 等等.
对应的Github repo 地址: https://github.com/zhaokang555/canvas-text-editor

2. 富文本编辑器(MVP)

2.11 鼠标事件

现在,我们来整理一下,迄今为止我们所需要的鼠标相关feature:

  • WHEN 鼠标hover到编辑器边缘的8个控制点(SizeControlPoint)上时, THEN 鼠标形状需要变化
  • WHEN 鼠标hover到编辑器边缘的虚线边框上时, THEN 鼠标形状需要变化
  • WHEN 鼠标hover到文字上时, THEN 鼠标形状需要变化(第1篇博文中提到的)
  • WHEN 鼠标点击某一个文字(字符)的半部分时, THEN 需要在它的面插入光标 AND 光标应该匹配其左侧文字样式
  • WHEN 鼠标点击某一个文字(字符)的半部分时, THEN 需要在它的面插入光标 AND 光标应该匹配其左侧文字样式
  • GIVEN 鼠标hover到文字上, WHEN 鼠标进行拖选时, THEN 需要高亮拖选中的文字

2.12 Mouse hover over SizeControlPoint

现在, 我们来实现这个feature: 当鼠标hover到编辑器边缘的六个控制点(SizeControlPoint)上时, 鼠标形状随之变化

之前, 我们渲染控制点的代码是写在src/core/CanvasTextEditor.ts中的:

如果继续这个类中处理鼠标相关逻辑, 这个类就会变得很臃肿. 所以, 我们需要重构一下代码, 把控制点相关的代码抽离出来.

2.12.1 重构: Extract component: SizeControlPoint

新建文件src/core/SizeControlPoint.ts:

image

然后, 我们还需要实现SizeControlPoint中依赖的两个接口: IBoundingBox, IRenderable.

新建src/core/IBoundingBox.ts:

image

新建src/core/IRenderable.ts:

image

然后, 将CanvasTextEditor中的renderBorderCircle方法稍加修改, 迁移到SizeControlPoint类中:

image

最后, 修改CanvasTextEditor类, 删除老代码, 引入SizeControlPoint:

2.12.2 架构设计: 引入概念: ResponsiveToMouseHover

image

2.12.3 自顶向下实现

首先, 修改src/core/CanvasTextEditor.ts:

  • 添加一个sizeControlPoints属性, 用来存放所有的控制点
  • renderBorder中渲染控制点相关的代码, 转移到构造函数中
  • 添加一个析构函数, 用来清理事件监听函数
  • clearCanvas中重置鼠标形状
  • render中渲染所有控制点

同时, 定义了一个枚举src/core/CursorType.ts, 用来存放目前所使用到的鼠标样式:

其中每个值的含义可以参考MDN的这个文档: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

然后, 修改src/core/SizeControlPoint.ts:

然后, 新建src/core/ResponsiveToMouseHover:

  • 实时监听鼠标位置, 存入mouseX, mouseX
  • 同时, 计算鼠标是否处于自身包围盒中, 将结果存入isMouseHovering
  • 在析构函数中移除监听函数

2.12.4 效果

(未完待续)

推荐阅读