从去年年初开始,我们团队内部就在做两个编辑器:
- 3d编辑器 支持搭建3d场景。
- 拓扑/大屏编辑器 支持搭建大屏/拓扑/组态场景。
开发编辑器的主要目是为了提高团队内部项目的交付效率,目前 两个编辑器都引用到团队的相关项目中。当然,编辑器目前也支持和其他公司的项目合作。下面是几个项目的示例图:
示例图
示例图2
示例图3
示例图4
中间是一个三维场景,使用三维编辑器编辑而成,周边是一些大屏元素,使用大屏编辑器编辑。
和一般的大屏编辑器不同,我们的大屏编辑器不仅支持大屏元素的排布,也支持分层拓扑图,架构图,交通图等,以及组态功能。基于canvas + HTML5元素共同开发,能够支持更多丰富的功能和效果。比如下面的拓扑效果:
拓扑图
架构图
还有轨道交通,地铁,交通线路图等:
交通线路
当然还有组态图,比如下面的电力一次接线图等。
接线图
在编辑器的开发过程中,经历了很多次的迭代,自我否定,然后是不断的成长。产品的开发过程中,我们需要对产品的设计进行深入的探讨。下面是一些感悟,和大家分享。本文主要是分享产品功能设计层面,而非软件开发架构。
易用性
易用性是一个很宽泛的概念。但其确实是一个产品设计中,最重要的一个因素,甚至可以说,易用性决定了产品的成败。产品是帮助用户来达到某个任务的,因此首先产品需要有可用性,可用性就是通过产品某项功能,能够达到逾期的目的。比如用户需要可以配置一个chart图表,而在编辑器中有chart图表配置的功能。产品的可用性就是要确保该产品能够正常的完成工作,这是最基本的要求。
但是光有可用性是远远不够的,要想一个产品能够得到认可,一定要在易用性上面下狠功夫。易用性是指最终给到用户使用的产品是否容易使用,通常情况下,易用性越差,用户越难以接受一款产品。
我们的产品在易用性方面也是做了很多努力的。比如编辑器中提供了一些常用的复制功能,能否方便使用者提高效率和精确度:
- 各种对齐功能
- 平均分布
- 等距排布
- 网格,自动吸附
- 批量复制
- 拖拽复制
- 组合与打散
- 锁定
- undo redo
- 。。。
以上功能,都是为了能够让使用者在使用的过程中更加容易。
易用性辅助按钮要做好易用性的工作,除了一些常用的辅助性工作外,还需要遵从一些其他的规则。比如
- 直观性 有时候,会不自觉的实现很多隐藏的功能,比如使用快捷键或者右键菜单。使用快捷键或者右键菜单要谨慎,比较忌讳的是一个功能,只有快捷键才能调出,而没有直观的按钮。并且快捷键没法快速查看,传递给用户的设计就是更为糟糕的。当然快捷键在有直观传递的情况下,有时候是可以增加用户使用效率的。
- 明确性,避免模糊性和歧义性 功能点的设计应该明确,不应该表达不清.
- 简单性 每个功能点 应该设计的相对简单,不应该把多个功能通过逻辑开关的方式整合在一起。
当然还有更多的易用性,后面涉及到的在做介绍。
通用性
有时候在遇到一些需求的时候,我们需要把具体的需求抽象成更抽象的需求;把特 殊的需求,提高成更加通用的需求。看似是把把简 单的需求复杂化了,但确实很有必要,因为其可以保持软件本身不会变的越来越臃肿。
比如曾经有这样的一个组件需求:
组件
类似于进度条的需求。要说实现这个组件本身,难度并不大,使用canvas的绘制,重复绘制很多矩形,通过数据来定义矩形重复的数量, 即可达到。
然而,其实可以从中间提前一个更加通用的规则,就是某个对象的重复绘制。在此,我们把具体的矩形 抽象成为更为抽象的某个对象。而某个对象如何定义呢?其实很简单,可以把我们现有的图元库中的所有图元作为“某个对象”,那么最终的需求就变成:
- 对于图元库中的所有图元,可以进行重复绘制,重复的次数通过数据来定义。
于是我们最终的定义了个RepeatNode的对象(重复节点的意思),RepeatNode可以指定一个图元进行重复,如下图所示:
重复节点
该节点对象,可以指定要重复的对象(前面红色框的矩形对象就是),可以指定重复此处,间距等等属性。当如重复次数还可以通过动态数据来驱动,以此达到动态的效果。
有了repeatnode,我们除了实现原始的需求效果外,还可以轻松的实现其他类似的效果,比如:
更多示例
后续还有个类似HTML5中tab标签的功能需求,要求能够点击按钮进行页面切换:
tab标签
编辑器前期是使用事件派发的机制来实现的,比如上面,点击保障措施,就脚本派发一个事件,然后相关的元素展示出来,而不相关的元素隐藏起来。
通过派发事件和接受事件来展示和隐藏内容,效果是可以的,问题在于易用性并不好,通过编辑器实现起来复杂,一般的实施人员用起来难度大。因此,可以考虑抽象出一个TabNode,有技术人员提出疑问是,tabNode的标题部分并不固定,可能各种变化。但是实际上,我们可以不按照普通的Tab的思路来做。TabNode只是要给一个Tab容器,该容器可以配置指定哪些元素作为tab标签的标题(这个和前面的RepeatNode类似),这样就解决了TabNode的标题可能各种变化的问题。
实际上,还是可以复用原本的事件派发的机制来实现TabNode的切换。
灵活性和易用性
灵活性和易用性有时候是相互矛盾的。比如前面说的TabNode的问题,用事件派发的脚本机制,肯定是最灵活的,因为脚本的机制可以实现几乎所有的需求变化,然而易用性却不好了。
既要灵活性,也有易用性。应该如何做呢?我比较认同的就是多层次的设计思路,最底层的是比较灵活的实现方式;在灵活的底层的基础上,我们在进一步的封装,把常用的功能和元素封装得更加易用。
比如前面TabNode就是这个思路。
还有编辑器支持echart图表和HtmlNode功能。echart的配置千变万化,如果把所有得配置项都抽出来,做成可视化得模式,工作量巨大,因此编辑直接提供了json配置,就很灵活,但是易用性差;而HtmlNode类似于Vue的模板机制,也是需要比较专业开发人员才能处理。
echart图表和HtmlNode都是灵活性很好得元素,但是易用性差。那么怎么解决呢?我们得思路是提供一个模板功能,把常用的项目上面做得好得配置,做成模板,放到模板库里面。后续非专业人员,可以从模板库中去选择,而不是手动去配置json或者html标签。
可扩展性
编辑器中最常见得变化就是图元得变化,因此我们提供了图元编辑器。通过图元编辑器可以编辑出各种需要的图元,同时也支持SVG图像的导入处理等,比如如下图项目中用到的图元就是:
扩展图元
上述的图元都有动态的效果,比如第一个三段式的,每段长度是可以变化的。第二个数量可变,第三个数量和高度可变。
上面只是举例说明,实际的编辑的图元非常多,也很灵活:
编辑的图元
同时,还提供了插件机制,可以适当的扩展原本的功能,便于实现项目的一些特殊的需求。
总结
上面是一些设计与思考,主要是基于拓扑/大屏编辑器的思考。为了有更好的产品,我们一直在努力的架构,设计与思考。