来,教你开发一款图形编辑器

简介: 前端西瓜哥

我是前端西瓜哥,今天教你怎么开发一款图形编辑器。

虽然说的是图形编辑器,其实也归为编辑器,和文本编辑器开发的思想很多地方是共通的。如果你做文本编辑器的开发,也可以看看。

编辑器是比较复杂的项目,由多个功能模块组合而成。要想编辑器的代码有优秀拓展性、可维护性,分模块解耦是非常重要的事情。

编辑器开发的最大工作是在交互上,基本上是围绕鼠标左键事件进行交互,并搭配键盘快捷键。

计算图形学也有涉及,但基本都是简单的知识,比如判断两个矩形是否相交。高级的计算机图形学知识涉及较少,主要是高级功能才会用到,通常我会找第三方库来实现。

所以,不需要太多知识,我们也是可以开发一款图形编辑器的,就是比较花时间。

我们先说说编辑器的几个重要的模块。

坐标模块

说到图形界面,不得不提的就是坐标。

画布是可以缩放拖拽的,真实屏幕上的坐标并不就是编辑器画布上的坐标,所以需要做一层转换。

一个编辑器也可能有多个坐标系统。

画布模块

画布的拖拽移动,以及缩放。

拖拽的实现,可以修改画布左上角坐标,或者用 transform 的 translate。

至于缩放,需要考虑的东西挺多的:

  • 通过鼠标缩放时,要考虑光标所在的位置,以此为缩放中心进行缩放。
  • 考虑最小能缩小到多小,最大能放大到多少。
  • 缩小到画布小于容器大小时,是否将画布居中。
  • 缩放的过程是要设置固定的比例,还是让用户随意缩放出有小数的比例。
  • 一键缩放比例 100% 或自适应窗口的逻辑。

历史记录模块

一款编辑器如果没有撤销重做功能,无论功能多么强大,它就是个半成品。

历史记录的实现通常为设计模式的 命令模式,将各种操作抽象成一个个命令类,在操作过程中创建的命令实例会维护到 undo 栈和 redo 栈中。

在编写交互逻辑时,需要注意 一些有过程性的操作不要生成多个命令

比如移动元素在鼠标释放前,不要生成多个移动命令放入历史记录中,否则撤销不友好。

又比如文本编辑器,快速输入内容时,不要每输入一个字就生成一个操作命令。而是设置一个时间,多长时间没输入才生成命令放到历史记录中。

工具模块

编辑器的独特功能就体现在工具模块上了,其他模块属于是基础建设。

工具模块有什么?最基础的有:

  • 选中移动工具。选中工具其实也很复杂:直接点击选中、选区选中、shift 多选少选、选中已经被选中的元素(移动)
  • 绘制图形工具。矩形、圆形、贝塞尔曲线等。
  • 拖拽画布工具。因为是高频操作。通常一些编辑器额外支持按着右键拖拽,或是按着空格键和鼠标左键拖拽。

工具类很多,那么怎么管理呢?

我们需要一个 toolManager 类,它的实现其实和 VueRouterReactRouter 一样的套路,只是我们不是通过修改路由来切换,而是点击工具按钮调用 API 来切换工具。切换时,对应的注册的工具模块会被挂载。

一个个工具模块,就好比 React 的组件,需要支持组建挂载、销毁等钩子。

在挂载的时候需要注册一些临时的快捷键事件方法,销毁时做事件方法销毁工作。

当然我们这个是交互比较重的编辑器,所以还要实现 mousedown、mouseover 之类的接口。

工具类要注重拓展性,最好做成插件的形式,让其他人可以自定义地添加自己开发的工具类。

图层模块

当一个事物变得复杂后,对其进行管理就非常重要,分组就是一种解决方案。

所以很多编辑器都支持图层。当然如果编辑器足够简单,可以不支持。

图层怎么理解?好比是一张张透明的纸叠在一起,然后我们从上往下看。然后我们分别在不同的纸上画画,顶部的非透明内容会遮挡住下方相同区域的内容。我们还可以隐藏或是移动其中任一图层,调整出我们想要的 “一幅画”。

如果没有图层,我们所有的内容都在一张纸上,我们就失去了很多可能性,基本上修改不能微调,要重画。

图层模块需要支持基础功能:

  • 显示隐藏
  • 锁定(无法操作。当然还有进阶的无法移动、透明像素锁定,可以考虑实现)
  • 选中(就是进入图层)
  • 重命名
  • 删除

还有些高阶也算比较高频的功能:向下合并、创建图层蒙版。

其他模块

  • 快捷键。分为全局快捷键和工具的局部快捷键。我看 hotkey-js 这个快捷键库貌似挺不错的。
  • 标尺模块。画布的顶部和左侧的固定标尺,能够对齐。
  • 元素相对位置辅助线展示
  • ...

技术选型

因为模块非常多,也会为了支持新的功能做一些较大的改动,甚至会做较大的重构。所以弱类型的 JavaScript 还是算了,必须得 TypeScript。

考虑到可移植性,建议将编辑器分为底层能力的 core 和提供交互能力的 UI 层。

这样我们就可以较轻松迁移到 Vue、React 等框架上。就比如 VSCode 的核心编辑器被抽离出为 Monaco Editor,你在 LeetCode 刷题时默认编辑器就是这个 Monaco Editor。

所以你或许可以考虑 monorepo 的多项目开发策略?不过我没有试过。

图形编辑器在底层技术实现上主要有:

  • Dom 元素:svg 或 div。比如 drawio、Boxy SVG、百度脑图。
  • Canvas:比如各种在线协作表格、figma

考虑到通过元素过多导致的网页渲染卡顿,Canvas 可以做渲染上的优化,可以支持大量数据的场景。你可以看各大厂商的在线表格,都是 Canvas 做的,因为只有这样才能支持上万行的表格。

Canvas 是图形编辑器的主流,但在开发上也会变得麻烦:不好调试、且可能需要自己写一套渲染引擎。

需要的知识

因为编辑器很复杂,所以架构要做好,否则无法维护。为此,你需要学习设计模式。

此外你需要学习一些简单的计算机图形学知识,比如图形的碰撞检测、颜色填充的算法等。当你在开发时遇到对应问题再去研究就好了。有些复杂的图形学知识,可能需要找找第三方图形库帮你解决咯。

Canvas 或 SVG 的 API 学习,看你用到什么底层技术了。

结尾

本文是我开发编辑器的一些粗浅的见解,希望能帮到你。如果你有编辑器相关的问题,可以给我留言,我会考虑将其作为下一篇文章的主题。

如果觉得有帮助,希望你能给我点个赞,这样我才能有东西更新编辑器相关的文章。

相关文章
|
6月前
|
JSON 数据可视化 图形学
Graphix: 轻量级、可插拔、OOP 式图形编辑器开发引擎
A lightweight, pluggable, object-oriented programming (OOP) style graphic editor development engine / 一个轻量级、可插拔、OOP 式图形编辑器开发引擎
116 2
|
3月前
|
存储 安全 数据安全/隐私保护
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
119 0
|
4月前
|
移动开发 前端开发 JavaScript
基于 HTML5 和 Canvas 开发的在线图片编辑器
基于 HTML5 和 Canvas 开发的在线图片编辑器
84 0
|
17天前
|
运维 Java Linux
【运维基础知识】掌握VI编辑器:提升你的Java开发效率
本文详细介绍了VI编辑器的常用命令,包括模式切换、文本编辑、搜索替换及退出操作,帮助Java开发者提高在Linux环境下的编码效率。掌握这些命令,将使你在开发过程中更加得心应手。
18 2
|
5月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
112 4
|
4月前
|
小程序
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
586 0
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
|
6月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
75 1
基于HTML5开发的Markdown在线编辑器
|
6月前
|
API 开发工具 C++
【专栏:工具与技巧篇】使用代码编辑器(VS Code/Sublime Text)提升开发效率
【4月更文挑战第30天】在VS Code与Sublime Text两大流行代码编辑器中,开发者可借助其高效特性提升编程效率。VS Code拥有丰富的插件生态、内置Git集成、强大的调试工具、智能提示和多文件导航功能。Sublime Text则以其轻量级、快速响应、多光标编辑及自定义构建系统见长。学习编辑器的键盘快捷键、自定义配置、使用内置终端以及键绑定和宏,将助开发者进一步提高开发效率。选择适合自己的编辑器并不断适应新技术是提升开发工作流的关键。
299 1
|
6月前
|
存储 前端开发 JavaScript
前后端分离模式开发的BS电子病历编辑器源码(Java)
前后端分离模式开发的BS电子病历编辑器源码(Java)
116 0
|
4月前
|
开发工具
vi编辑器,现在vi\vim是文本文件进行编辑的最佳选择,Vim是vi的加强的版本,兼容vi的所有指令,vim编辑器有三种工作模式,一开始进入的是命令模式,命令模式i是插入的意思,两下y+p复制内容
vi编辑器,现在vi\vim是文本文件进行编辑的最佳选择,Vim是vi的加强的版本,兼容vi的所有指令,vim编辑器有三种工作模式,一开始进入的是命令模式,命令模式i是插入的意思,两下y+p复制内容