前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >图形编辑器基于Paper.js教程23:调研在canvas上书写多行文本,分析fabricjs的IText类的实现

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

作者头像
拿我格子衫来
发布2025-02-18 11:07:47
发布2025-02-18 11:07:47
4500
代码可运行
举报
文章被收录于专栏:TopFETopFE
运行总次数:0
代码可运行

背景

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

IText

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

代码语言:javascript
代码运行次数:0
复制
 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支持的 书写文本的交互

代码语言:javascript
代码运行次数:0
复制
 * #### 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来计算的。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • IText
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档