用Canvas实现文本编辑器(支持艺术字渲染与动画)

导言

目前富文本编辑器的实现主要有两种技术方案:一个是利用contenteditable属性直接对html元素进行编辑,如draft.js;另一种是代理textarea + 自定义div + 模拟光标实现。对于类似"word"的经典富文本编辑器,一般会采用以上两种技术方案之一,而不会考虑用canvas实现。

事实上,官方最佳实践中已经特别声明了不推荐用canvas实现编辑器,详见https://www.w3.org/TR/2dconte...
不推荐的原因包括光标位置维护、键盘移动的实现、以及没有原生文本输入处理等等。

既然如此,为何还要用canvas制作文本编辑器呢?这是因为对一些特殊的创作来说,canvas能更好的实现展示需求。比如艺术字效果的渲染,以及文本、背景动画等。

基于这点想法,便有了“简诗”这个自娱自乐的小项目。

简诗是为短诗文创作而开发的文本编辑器,主要面向中文写作。中文最特别之处便在于其笔画,所以在开发之初,我便想对文字进行处理之时,一定要把汉字进行笔画分割,以便实现更多有趣的效果的。

项目中文字由WebGL进行渲染。基本思路是先根据用户选择的字体,将文字写在离屏canvas上,然后利用getImageData api获取文字像素数据,进行连通域查询、分割、边缘查找及三角化后,由WebGL进行渲染。

(注:这种处理方式的好处是对任意系统支持的字体都可以实现艺术效果,而无需额外的字体开发。目前项目中没有引入字体文件,用到的字体都是Mac内置的字体,Mac用户如发现其中有的字体系统没有默认安装,只需到“字体册”中安装一下即可)

这一系列过程会单开一篇文章来写,本文主要描述canvas编辑器核心的实现。

实现效果

图片描述

预览地址:https://moyuer1992.github.io/...
源码地址:https://github.com/moyuer1992...

技术关键点

文字键入(代理输入框)

用canvas实现编辑器最关键的一点就是如何监听键盘文字输入,如果通过键盘事件自己处理,英文尚可,中文肯定是不可行的。所以还是需要使用原生textarea做一层代理。

代理textarea输入框是不可见的。这里需特别注意下,若用display: none隐藏输入框,则无法触发focus事件,所以输入框需要利用z-index来做隐藏。

当用户点击canvas时,程序控制触发textarea的focus事件,继而用户输入时,也自然触发了textarea的input事件:

var pos = this._convertWindowPosToCanvas(e.clientX, e.clientY);
if (pos.x !== -1 && pos.y !== -1) {
  this.focus(pos.x, pos.y);
} else {
  this.blur();
}
focus (x, y) {
  var pos = this.findPosfromMap(x, y);
  this.selection.update(pos.row, pos.col);
  this.updateCursor();
  this.$input.focus();
  this.$cursor.css('visibility', '
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值