Recent Posts
Quill 编辑器(三)复制粘贴 Clipboard
Published:Quill 编辑器(二)文档模型 Parchment
Published:Quill 编辑器(一)数据模型 Delta
Published:Arc 浏览器的个人体验
Published:
Recent Memos
10. 关于如何在 canvas 上选中一个元素
Published:大三的时候上过一门面向对象的课程,期末要做个小项目,要尽可能使用面向对象的思想,不限制编程语言。
当时的我正在为即将到来的秋招做准备,便借此机会做了一个简单的 Canvas 绘图工具,可以添加一些基础形状(矩形、菱形、圆形、椭圆、三角形等)、文本框、画笔工具,工具栏 UI 照着 Figma 做的。
当时需要实现点击选中元素功能,我是通过遍历所有元素,计算点击位置是否在元素的区域内来实现的。如果有多个元素重叠,就比较头疼,需要再额外处理一下层级。
时隔 4 年,我又一次接触这类 Canvas 应用,看到了其他人对这个问题的一种非常完美的解决思路:
原始 Canvas 称为 c1,新增一个与其完全一致的 c2,每个元素在触发 draw 方法时,不仅在 c1 上进行绘制,还要在 c2 上绘制自己的包络区域,用一种随机的 rgb 值作为颜色值。并存储这样的(元素, color)键值对。
当触发点击时,先获取点击坐标在 c2 上的色值,再通过色值直接拿到对应的元素。这种做法也可以很好地处理多个元素重叠的层级问题。
非常妙。
这种做法叫做「像素标记法」。
9. 移动端软键盘真的折磨人
Published:业务场景:点击 quill 中的图片元素,展示图片编辑框(有裁剪、修改尺寸之类的功能),但同时会唤起软键盘,产品诉求不希望唤起。
原因分析:quill 容器是
contenteditable=true
的元素,图片元素在该元素内部,只要图片触发 touch 动作,事件冒泡到 quill 容器,就会触发 focus 事件,进而唤起软键盘。尝试了一些方案,比如 click 事件中
prevent/stop/capture
,各种组合都不行。 后来发现在 touchstart 时 prevent + stop 可以避免 quill 发生 focus,但是同时连该区域的页面滑动都阻止了,并不合适。硬控我一整天,才找到一个解决方案: 在 touchstart 时将 quill 禁用(
contenteditable=false
),并在 touchcancel/end 时延迟一段时间(比如 200ms)再激活 quill。只读的容器,不可 focus,软键盘想弹都没机会。
这个方案实际只是凑合,很不优雅。
调研了其他产品在移动端网页上的体验,只发现了金山文档可以做到点击图片不唤起软键盘。
它是基于 ProseMirror 的,但是 ProseMirror 自己做不到,金山文档重新设计了光标选区和输入逻辑,并未将整个容器设置为
contenteditable=true
,而是创建了一个虚拟输入框(一个contenteditable=plaintext-only
元素)专门接收输入,位置放在光标处,整个页面除了它,用户随便点,都不会触发 focus,所有 focus 行为都由开发者控制。它这种做法,有点像 canvas 编辑器上的输入方案,但是竟然挪到了 dom 的编辑器上用。确实有点东西的。
我打算在 quill 上试一试。