《从零开始, 开发一个 Web Office 套件》系列博客目录 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office 套件, 包括: 文档, 表格, 幻灯片... 等等. 对应的Github repo 地址: https://github.com/zhaokang555/canvas-text-editor
z-index
上一篇博客中, 我们实现了mouse hover over SizeControlPoint的feature. 现在, 问题来了: SizeControlPoint和editor border会有重叠的部分, 当鼠标hover到这个位置时, 应该怎么处理?
我暂时想到了一种解决方案: 引入z-index
的概念, 为SizeControlPoint和editor border分配不同的z-index
. 当鼠标hover到元素重叠的部分时, 寻找最大的z-index
对应的元素.
修改src/core/ResponsiveToMouseHover.ts
:
zIndex
options
, 用来设置zIndex
topLayerZIndex
和topLayerCursorType
, 用来记录最上层图层对应的zIndex
值和鼠标样式topLayerZIndex
和topLayerCursorType
同时, 修改src/core/SizeControlPoint.ts
, 让它支持设置zIndex
:
最后, 修改src/coreCanvasTextEditor.ts
:
render
函数, 在所有的sizeControlPoints
render结束之后, 再设置canvas.style.cursor
clearCanvas
函数, 重置ResponsiveToMouseHover.topLayerZIndex
和 ResponsiveToMouseHover.topLayerCursorType
处理完z-index
的问题, 我们就可以实现这个feature了: 当鼠标hover到编辑器边缘的虚线边框上时, 鼠标形状随之变化
CanvasTextEditorBorder
新建文件src/core/CanvasTextEditorBorder.ts
:
其中, Victor
是一个开源数学库: http://victorjs.org/, 可以做一些二维向量计算, 可以通过npm安装:
npm install victor --save
npm install @types/victor --save-dev
然后重构文件src/core/CanvasTextEditor.ts
:
constructor
, 抽出initParagraphs
和initSizeControlPoints
函数initBorder
函数, 并在constructor
中调用renderBorder
函数render
函数同时,修改CanvasTextEditor.destructor
, 在其中调用每个border实例的destructor
:
实现这个feature之前, 我们需要思考如何拓展border的响应范围(responsive zone). 为什么要这样呢? 因为border是一条很细的线, 要让鼠标精确地hover上去非常困难, 所以要扩大它的responsive zone. 如下图所示, 我们把border横向拓展, 灰色的范围就是拓展后的responsive zone.
然后, 我们动手来实现. 修改src/core/CanvasTextEditorBorder.ts
:
ResponsiveToMouseHover
borderResponsiveWidth
, 用来表示拓展后的responsive box的宽度defaultCanvasTextEditorBorderZIndex
, 用来表示border默认的zIndex
constructor
中: normalVector
responsive zone
的四角坐标, 存入points
中responsive zone
的left, top, width, height
, 传入super()
中上图中,我们使用了Victor
(http://victorjs.org)这个二位向量运算库的若干API:
.clone()
: 克隆一个二维向量,并返回.substract(vector)
: 用自己减去另一个二维向量,并将结果赋值给自己.add(vector)
: 用自己加上另一个二维向量,并将结果赋值给自己.rotate(angle)
: 将自己沿原点旋转若干弧度,并将结果赋值给自己.normalize()
: 将自己标准化,并将结果赋值给自己.multiplyScalar(scalar)
: 将自己乘以一个数量,并将结果赋值给自己同时, 在src/core/CursorType.ts
中, 添加十字鼠标样式(see: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor) :
给responsive zone
加上灰色背景, 看一下它的范围是否合适:
(未完待续)