这段时间承蒙你们厚爱,给了我至关大码字的动力,决定节前再更一弹。最近养成了回顾总结的好习惯,sf真是个不错的地方。前端
最近忙着给客户折腾一个复杂的多层嵌套关系。客户一句话“要好看!”,哥就忙白了头啊,还好赶在节前解决了,否则真的要随广大股民排队投江庆祝端午了。node
先简单描述下此次客户的需求。canvas
现实应用中,网络拓扑图结构可能很简单,也可能很是复杂。浏览器
好比这种节点较多的单层拓扑:网络
稍复杂一些的:spa
再复杂一些的:插件
在这些拓扑图中常见的场景是,不少网络节点须要组成一组,这常被称为“网元组”。通常来讲,网元组会有一个形状,双击能够展开/闭合。例以下图中的像以下:设计
此次客户的需求中,最大的难点就是须要有五层网元组的嵌套,五层同时展开时,要求清晰美观。常规的分组形状有圆形、矩形、平行四边形等,不管哪一种形状,分组多了后,就会产生审美疲劳。好比,我让设计师mm简单地把五层嵌套画个图,它看起来会是这样:rest
我把这个图给客户看了之后,客户表示但愿“结构可以更加清晰”。那天,魔都大雨倾盆,我抓耳挠腮一个下午,终于有了一些灵感。code
怎样才能使得结构效果更加清晰?我想到的是用颜色。颜色永远是图形设计里面的第一要素。若是分组颜色千篇一概,天然就看不太清楚包含关系。可是颜色太多五光十色,显然也不符合电信UI系统的风格。那颜色要如何设置呢?层层嵌套的分组,层层……叮!你有没有想到一种蔬菜?
(此处哼唱“若是你能够一层一层一层地剥开个人心……”一百遍……)
这颗大洋葱看上去井井有条,是由于它的颜色从内到外有必定规律的变化:渐变。说到渐变,又想起最近GF推荐的一枚游戏,大概内容是按照颜色的渐变规律来排列一些方块。(很无聊有没有?)
不过,前端设计中,配色却是很重要的一个环节。
总之,想好了用渐变的配色来使嵌套组更清晰后,就大胆地尝试一下:
var group = new twaver.Group(); group.setStyle('group.fill.color', style[3]); group.setStyle('group.deep', 0); group.setStyle('group.outline.width', style[1]); group.setStyle('group.outline.color', style[0]); group.setStyle('group.shape', 'roundrect'); group.setStyle('select.style', 'none'); group.setStyle('vector.outline.pattern', style[2]); group.setStyle('label.font', '14px "Microsoft Yahei"'); group.setStyle('whole.alpha', 0.8); group.setStyle('group.padding', -10); group.setStyle('label.position', 'topright.topleft'); group.setName(name); group.setLocation(100+150*level, 300); box.add(group);
数据量更大的时候,看看分组是否是会更加清晰?
这个图作出来以后,拿给周围几个同事看,你们纷纷表示不错,可是彷佛有一些死板,不够生动。生动。。那就是要活灵活现的,因而我继续抓耳挠腮,又想到了一些瓜果蔬菜:
果真仍是配色不够明艳啊。我又让设计师mm给找了几个色值调整了一下:
有了写花瓣层叠的感受,是否是舒服多了?不过,方方正正的组的形状,仍是太死板,缺少立体感。看到桌子上的一张折了角的白纸,忽然有了灵感。
给方形的组作一个折角效果,不知效果如何。要作这个效果,就要重写group的绘制,本身接管2d绘制了。Group的形状将再也不是一个矩形,而是一个切角的矩形。
//draw round rect body.
var roundRadius=10; ctx.save(); ctx.beginPath(); ctx.moveTo(rect.x+roundRadius, rect.y); ctx.lineTo(rect.x+rect.width-60, rect.y); ctx.lineTo(rect.x+rect.width, rect.y+28); ctx.lineTo(rect.x+rect.width, rect.y+rect.height-roundRadius); ctx.quadraticCurveTo(rect.x+rect.width, rect.y+rect.height, rect.x+rect.width-roundRadius, rect.y+rect.height); ctx.lineTo(rect.x+roundRadius, rect.y+rect.height); ctx.quadraticCurveTo(rect.x, rect.y+rect.height, rect.x, rect.y+rect.height-roundRadius); ctx.lineTo(rect.x, rect.y+roundRadius); ctx.quadraticCurveTo(rect.x, rect.y, rect.x+roundRadius, rect.y); ctx.save(); ctx.shadowOffsetX = 4; ctx.shadowOffsetY = 4; ctx.shadowBlur = 4; ctx.shadowColor ="#555555"; ctx.fill(); ctx.restore(); ctx.lineWidth=node.getStyle('group.outline.width'); ctx.strokeStyle=node.getStyle('group.outline.color'); ctx.stroke(); ctx.restore();
经过绘制一个带圆角的矩形并切掉一个角,stroke到画布上。看看效果:
再经过增长圆角、切角、增长阴影、设置不一样的边框线宽,让分组进一步产生“层层递进”的感受。如今就剩下画折角的细节了。
折角这里,须要画一个被折下来的直角三角形。三角形的颜色,应该是“纸”的背面颜色。这里当心定义三角形的形状,并进行填充:
//draw corlor.
ctx.fillStyle=node.getStyle('group.outline.color'); ctx.lineWidth=node.getStyle('group.outline.width'); ctx.lineJoin='bevel'; ctx.beginPath(); ctx.moveTo(rect.x+rect.width-60, rect.y); ctx.lineTo(rect.x+rect.width-23-10, rect.y+47-10); ctx.quadraticCurveTo(rect.x+rect.width-23, rect.y+46, rect.x+rect.width-23+10, rect.y+47-10); ctx.lineTo(rect.x+rect.width, rect.y+28); ctx.closePath(); ctx.save(); ctx.shadowOffsetX = 4; ctx.shadowOffsetY = 4; ctx.shadowBlur = 4; ctx.shadowColor ="#777777"; ctx.fill(); ctx.restore(); ctx.strokeStyle=node.getStyle('group.outline.color'); ctx.stroke();
效果以下,立体感出来之后,是否是生动了不少?
这里要注意的是,折角的阴影也要设置,而且填充要使用和边框相同的颜色,增长“折纸”的立体感。
折纸效果有了,不过左侧上方略显空旷,因而利用canvas的2d来练练手,画个path看看:
ctx.save(); ctx.strokeStyle='#27A3DA'; ctx.lineWidth=2; ctx.beginPath(); ctx.moveTo(rect.x+31, rect.y+5); ctx.lineTo(rect.x+25, rect.y+20); ctx.bezierCurveTo(rect.x+25, rect.y+26, rect.x+28, rect.y+28, rect.x+32, rect.y+23); ctx.lineTo(rect.x+42, rect.y-2); ctx.bezierCurveTo(rect.x+42, rect.y-12, rect.x+32, rect.y-10, rect.x+32, rect.y-5); ctx.lineTo(rect.x+29, rect.y-1); ctx.shadowOffsetX = 1; ctx.shadowOffsetY = 1; ctx.shadowBlur = 1; ctx.shadowColor ="#aaaaaa"; ctx.stroke(); ctx.restore();
运行一下,你猜是神马?
哈哈,一个小回形针瞬间跃然纸上了,感受萌萌哒!为了增长立体感,回形针也是要设置阴影的,不过偏移不要太大、颜色要淡一些,像这样:
适当明艳的色彩,加上折角、阴影和小回形针,这回这个层层嵌套总算是清晰又好看了吧?
运行一下,拖拖拽拽,由于以前已经作了很多图标、线条的样式,因此整体效果仍是很不错的!
最后仍是想唠叨几句HTML5的canvas,虽然已经不是什么新鲜技术了,但直接在浏览器中绘制网络拓扑图的逻辑关系,而不须要安装任何插件,对于不少正在更新换代的OSS系统来讲,仍是颇有吸引力的。当技术自己再也不有壁垒,咱们更应该注重的是实际业务中应用,好比在画这种组织结构关系很是复杂的拓扑图时,如何让图形更加清晰、易懂,让技术真正落到实处。