图形编辑器基于Paper.js教程23:调研在canvas上书写多行文本,分析fabricjs的IText类的实现

背景

近期要重构矢量文本的功能,于是尽可能多的收集了这一类的功能实现,最后开始看fabricjs的文本书写的实现。于是阅读了一些源码,这里稍稍记录一下,一次阅读肯定吃不透它的所有实现。

IText

当我们在fabricjs的画布上创建一个文本元素时,大概会这样写

 const text = new fabric.IText("双击输入文本", {
   left: x,
   top: y,
   fontSize: 20,
   fill: "black",
   editable: true,
 });

 // 添加到画布
 this.canvas.add(text);

关于 IText类的详细文档
https://fabricjs.com/api/classes/itext/#acoords 支持的属性非常多

查看源码可以得知在new时,主要执行了这两段代码
在这里插入图片描述

initBehavior 这个方法是在ITextClickBehavior 这个抽象类里实现的
在这里插入图片描述

另外是 fabricjs支持的 书写文本的交互

 * #### Supported key combinations
 * ```
 *   1: Move cursor:                    left, right, up, down
 *   2: Select character:               shift + left, shift + right
 *   3: Select text vertically:         shift + up, shift + down
 *   4: Move cursor by word:            alt + left, alt + right
 *   5: Select words:                   shift + alt + left, shift + alt + right
 *   6: Move cursor to line start/end:  cmd + left, cmd + right or home, end
 *   7: Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
 *   8: Jump to start/end of text:      cmd + up, cmd + down
 *   9: Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
 *   10: Delete character:               backspace
 *   11: Delete word:                    alt + backspace
 *   12: Delete line:                    cmd + backspace
 *   13: Forward delete:                 delete
 *   14: Copy text:                      ctrl/cmd + c
 *   15: Paste text:                     ctrl/cmd + v
 *   16: Cut text:                       ctrl/cmd + x
 *   17: Select entire text:             ctrl/cmd + a
 *   18: Quit editing                    tab or esc
 * ```
 *
 * #### Supported mouse/touch combination
 * ```
 *   19: Position cursor:                click/touch
 *   20: Create selection:               click/touch & drag
 *   21: Create selection:               click & shift + click
 *   22: Select word:                    double click
 *   23: Select line:                    triple click
 * ```

这23个没有包含换行,特殊字符等处理。可以说非常切合地mock里在文本域中的交互。

在ITextKeyBehavior.ts 这个文件里有写到是使用的 一个隐藏的textarea来实现的 输入效果,包括选择,光标的上下左右移动,复制粘贴
在这里插入图片描述

我看的几个方案都是 使用隐藏的textarea来mock,书写动作。

当点击画布时,真实的光标聚焦在隐藏的textarea的中,并在画布上画一个隐藏的光标,并设置动画。
同时监听textarea的这些事件 blur, keydown,keyup ,input ,copy ,cut ,paste ,compositionstart ,compositionupdate ,compositionend ,在这些事件的处理函数中,都需要将内容的修改,或者状态,同步到画布的文本元素上。

在移动画布上的光标时,或者选择内容时,我们必须对字体的宽度和位置有一个清晰的建模。
而这个建模 就是使用 canvas.measureText() 这个方法。
https://developer.mozilla.org/zh-CN/docs/Web…/API/CanvasRenderingContext2D/measureText

在 Text.ts这个文件里我们可以找到相关的代码,在这里插入图片描述

像 this.__charBounds, this._textLines ,每一行的宽度,每个字体的宽度,都是基于这个measureText来计算的。

每一字符都有一个索引,即使换行也不间断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿我格子衫来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值