尝试在 Canvas 中执行此操作有点令人不悦。HTML5 Canvas 规范本身强烈建议不要尝试这样做。正如规范所说:
作者应避免使用 canvas 元素实现文本编辑控件。这样做有很多缺点:
- 必须重新实现插入符号的鼠标放置。
- 插入符号的键盘移动必须重新实现(可能跨行,用于多行文本输入)。
- 必须实现文本字段的滚动(水平滚动用于长行,垂直滚动用于多行输入)。
- 必须重新实现诸如复制和粘贴之类的本机功能。
- 必须重新实现拼写检查等原生功能。
- 必须重新实现拖放等原生功能。
- 必须重新实现页面范围的文本搜索等原生功能。
- 必须重新实现特定于用户的本机功能,例如自定义文本服务。这几乎是不可能的,因为每个用户可能安装了不同的服务,并且可能存在无限多的此类服务。
- 双向文本编辑必须重新实现。
- 对于多行文本编辑,必须为所有相关语言实现换行。
- 必须重新实现文本选择。
- 必须重新实现双向文本选择的拖动。
- 必须重新实现平台原生键盘快捷键。
- 必须重新实现平台原生输入法编辑器 (IME)。
- 撤消和重做功能必须重新实现。
- 必须重新实现可访问性功能,例如插入符号或选择之后的放大。
在 Canvas 中实现这些东西是一场噩梦,尤其是在今天,相同的字体不仅在每个浏览器中看起来不同,而且在 Canvas 渲染字体和浏览器渲染字体之间看起来也不同。
我建议您查看 Mozilla Bespin 的代码,它是用画布制作的。它最终变成了 Mozilla Skywriter,然后最终他们说“Welp canvas 是这项工作的错误工具”,放弃并与 Ace 合并,后者不使用 Canvas 而是使用 DIV。如果您真的对这类事情感兴趣,那么我强烈建议您查看这些项目的代码。当我刚开始使用 Canvas 时,bespin 代码帮助了我很多。
最重要的是,如果您正在编辑文本,请在画布上使用 DIV 和输入以及其他 HTML 元素(暂时)。不要试图在画布中模仿它。无论如何,您都可以尝试,但您将度过一段糟糕的时光,您的用户也是如此。
至于画布上的多行文本,你现在必须自己计算。您甚至必须近似文本高度。
我对实际实现一个简单的编辑器的建议是:有一个画布,绘制一些文本,也许在一些复杂的图形上。当您想编辑文本时,可能通过单击图形,在单击事件上出现一个(多行或不多行)HTML Input 元素。在按下回车、退出或框失去焦点(blur
事件)后,提交更改。