《从零开始, 开发一个 Web Office 套件》系列博客目录

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

对应的Github repo 地址: https://github.com/zhaokang555/canvas-text-editor

2. 富文本编辑器(MVP)

2.13 z-index

2.13.1 新的问题

上一篇博客中, 我们实现了mouse hover on SizeControlPoint的feature. 现在, 问题来了: SizeControlPoint和editor border会有重叠的部分, 当鼠标hover到这个位置时, 应该怎么处理?

我暂时想到了一种解决方案: 引入z-index的概念, 为SizeControlPoint和editor border分配不同的z-index. 当鼠标hover到元素重叠的部分时, 寻找最大的z-index对应的元素.

2.13.2 实现

修改src/core/ResponsiveToMouseHover.ts:

  • 添加属性zIndex
  • constructor添加形参options, 用来设置zIndex
  • 添加两个静态属性topLayerZIndextopLayerCursorType, 用来记录最上层图层对应的zIndex值和鼠标样式
  • 修改render函数, 记录topLayerZIndextopLayerCursorType

同时, 修改src/core/SizeControlPoint.ts, 让它支持设置zIndex:

最后, 修改src/coreCanvasTextEditor.ts:

  • 修改render函数, 在所有的sizeControlPoints render结束之后, 再设置canvas.style.cursor
  • 修改clearCanvas函数, 重置ResponsiveToMouseHover.topLayerZIndexResponsiveToMouseHover.topLayerCursorType

2.14 Mouse hover on editor border

处理完z-index的问题, 我们就可以实现这个feature了: 当鼠标hover到编辑器边缘的虚线边框上时, 鼠标形状随之变化

2.14.1 重构: Extract component: 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, 抽出initParagraphsinitSizeControlPoints函数
  • 添加initBorder函数, 并在constructor中调用
  • 删除renderBorder函数
  • 修改render函数

2.14.2 实现

实现这个feature之前, 我们需要思考如何拓展border的响应范围(responsive zone). 为什么要这样呢? 因为border是一条很细的线, 要让鼠标精确地hover上去非常困难, 所以要扩大它的responsive zone. 如下图所示, 我们把border横向拓展, 灰色的范围就是拓展后的responsive zone.

然后, 我们动手来实现. 修改src/core/CanvasTextEditorBorder.ts:

  • 继承ResponsiveToMouseHover
  • 添加常量borderResponsiveWidth, 用来表示拓展后的responsive box的宽度
  • 添加常量defaultCanvasTextEditorBorderZIndex, 用来表示border默认的zIndex
  • constructor中:
    • 计算border的法向量normalVector
    • 然后计算responsive zone的四角坐标, 存入points
    • 然后利用四角坐标, 计算responsive zoneleft, top, width, height, 传入super()

上图中,我们使用了Victorhttp://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) :

2.14.3 效果

responsive zone加上灰色背景, 看一下它的范围是否合适:

(未完待续)

最新文章

  1. 5.Inheritance Strategy(继承策略)【EFcode-first系列】
  2. js查找水仙花数
  3. 原生态jdbc的应用技术
  4. tamper绕WAF详解
  5. 友盟推送里面的Alias怎么用?可以理解成账号吗?
  6. hdu Oil Deposits
  7. oracle 直接客户端使用
  8. How to change the property of a control from a flowlayoutpanel?
  9. Newtonsoft.Json工具类
  10. [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】
  11. [置顶] NB多项式事件模型、神经网络、SVM之函数/几何间隔——斯坦福ML公开课笔记6
  12. phpstorm显示行号
  13. Android学习——移植tr069程序到Android平台
  14. macOS webview编程
  15. 【转载】 spring事物配置,声明式事务管理和基于@Transactional注解的使用
  16. Redis_简单使用
  17. dom操作------创建节点/插入节点
  18. CentOS7.x使用overlay文件系统
  19. 【struts2】自定义拦截器
  20. Linux内核同步 - RCU基础

热门文章

  1. HTML5元素
  2. JMM模型基础知识笔记
  3. 【Java】final
  4. vue3知识点的自我总结
  5. TC (Teamcenter) 许可证解决方案
  6. 【解决了一个小问题】如何展示VictoriaMetrics组件上报的bucket数据
  7. 从带Per-Building数据的KML/COLLADA中创建3D Tiles
  8. CSS设置标签、图片放大、缩小、旋转、移动(tranform)
  9. zabbix安装 报错 socket '/var/lib/mysql/mysql.sock' (13)]
  10. rsync.sh