一、项目概述
1.1 项目功能
本项目的最终结果是一个同时具有流程图和思维导图功能的Web版制图软件。能够制作出如下图所示的图:
项目具有以下的一些功能:
-
类似软件的常规功能:元件库、分组管理、层次管理、锁定管理、图形样式、文字样式、连接线样式等。
-
用户可添加自定义图片,包括png、jpg、gif、svg等格式,以及一种项目自定义的格式。
-
流程图和思维导图可同时在一个页面中完成编辑。
-
思维导图可变换左侧、右侧、底部、双侧等模式。
-
整图转换为png、svg、jpg等格式。
-
文本支持内部多种样式。如下图所示:
-
图元支持自定义连接锚点以及文字位置。如下图所示:
-
磁吸、对齐线、图元距离等辅助和提示功能。如下图所示:
1.2 项目难点
开发此项目存在几大难点,分别是:
鼠标动作处理
单纯对于流程图来说,鼠标动作的处理就相当复杂。虽然鼠标的动作不外乎就是DOWN/OVER/UP,但加上辅助键CTRL/SHIFT,在不同的场景下的组合就变得很复杂。例如单击一个图元,如果本身没选择任何图元,那么选中这个图元;如果本身有选中其他图元,那么取消旧图元的选中,再选中这个图元;如果同时按下了CTRL键,那个不取消旧的选中,而是加入此图元的选中,变成多选;如果单击之后没有马上弹起,而是移动了鼠标,则图元跟随鼠标移动;如果同时按下了CTRL键,那么需要先复制一份,选中复制的图元,再进行移动……
加入了思维导图之后,鼠标动作的处理变得更加复杂,因为要处理的情况更多,容易变得混乱。
图元数据描述
在项目中,可以看到这些图元:图形、图片、文字、连接线、思维导图结点等。每种图元都有自己的一些特殊属性,例如在图形里,矩形和直线是比较特殊的:矩形有一个圆角的属性,直线没有矩形框、没有填充颜色。连接线有线帽类型、线类型(直线、折线、曲线)等属性。双击图片没有文字。有些图元里的文字超出图元范围就隐藏,有些则改变图元的尺寸以适配文字的大小。图元中有多个锚点,可供连接线绑定。
项目中所有的图元都有一个基类,要整理出描述图元的数据结构是不容易的。还要处理好相同的操作对于不同的图元的作用效果。
几何计算
项目中涉及到一些图形的几何计算,例如是鼠标拖拉图元变换、连接线的自动生成、点是否在图形内、磁吸和对齐线、思维导图节点位置计算等。其中有一些计算是比较复杂的,例如旋转之后的变换、合成组之后整组变换时的内部变换。又如判断点是否在Bezier曲线上、求出跟离曲线最近的点。
文本处理
在HTML中,在一个div里加上contenteditable="true"属性之后,它就变成了一个可编辑的框,而且是支持富文本的编辑框。JavaScript中使用execCommand()命令去修改编辑框中的文本样式。可惜的是,execCommand已经被弃用,而且暂时没有替代方案。本项目需要使用实现这个替代方案。另一方面,在SVG中可以使用foreignObject显示div文本,但在一个独立的SVG文件中,foreignObject里的文本不会显示出来。项目有下载SVG的需求,也就是存在将div文本转成svg文本的需求。两者存在某些差异(特别是SVG中文本不能自动换行),导致这一转换过程相对复杂。
整体架构
整个项目的代码规模是比较大的,而且不是把不同的功能放在不同的页面这么简单。基本上所有的功能都在一个页面里,这其中涉及到鼠标、按键、画布、选择、历史记录、图元、光标、状态等众多概念。需要使用优良的架构去组态代码和功能,才能控制项目的开发难度和保证项目的可维护性。
1.3 技术选型
1.3.1 SVG和Canvas的选用问题
SVG和Canvas都是Web版画图软件常用的绘图技术,SVG更适合矢量图,Canvas更适合位图。以下是两者的优劣对比:
-
Canvas在图形绘制时会有模糊的情况出现,特别是文字,很难做到清晰。而SVG无论怎么缩放,都是比较清晰的。
-
使用Canvas会使系统架构相对简单一些。由于Canvas每次修改都是重绘,只需要管理好后台数据,然后统一交给渲染代码即可。而使用SVG,需要同时管理后台数据和前台的视觉元素,在修改的时候,两者需要同步。
-
SVG中可以添加动态的GIF图片,但在Canvas中难以做到。GIF本身的动画需要使用一个线程去管理,一帧一帧地去画,但JavaScript又是单线程的,实现就会很复杂。
-
当存在大量图元动态变化时,Canvas具有优势。在SVG中,如果每个图元不是作为一个整体变化,那么就需要每个图元标记ID去管理。当图元数量众多且比较小的时候,这种方法比较笨重。
-
SVG描述颜色渐变比较复杂,需要事先定义一大段内容,不能灵活使用。
由于本项目主要处理的是图形,也会使用GIF图,所以更适合使用SVG。
1.3.2 项目技术选用
领域 | 选用技术 |
---|---|
绘图技术 | SVG |
前端框架 | Vue |
前端开发语言 | TypeScript |
后端开发语言 | C# |