這段時間承蒙你們厚愛,給了我至關大碼字的動力,決定節前再更一彈。最近養成了回顧總結的好習慣,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系統來講,仍是頗有吸引力的。當技術自己再也不有壁壘,咱們更應該注重的是實際業務中應用,好比在畫這種組織結構關係很是複雜的拓撲圖時,如何讓圖形更加清晰、易懂,讓技術真正落到實處。