TWaver - 專注UI技術(shù)

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          前言 

          最近忙著給客戶折騰一個(gè)復(fù)雜的多層嵌套關(guān)系。客戶一句話“要好看!”,哥就忙白了頭啊,還好最終搞定了。

           

          需求描述 

          先簡(jiǎn)單描述下這次客戶的需求。

          現(xiàn)實(shí)應(yīng)用中,網(wǎng)絡(luò)拓?fù)鋱D結(jié)構(gòu)可能很簡(jiǎn)單,也可能非常復(fù)雜。

          比如這種節(jié)點(diǎn)較多的單層拓?fù)洌?br />


          稍復(fù)雜一些的:


           

          再?gòu)?fù)雜一些的:


           

          在這些拓?fù)鋱D中常見的場(chǎng)景是,很多網(wǎng)絡(luò)節(jié)點(diǎn)需要組成一組,這常被稱為“網(wǎng)元組”。一般來說,網(wǎng)元組會(huì)有一個(gè)形狀,雙擊可以展開/閉合。如下圖:


           

          這次客戶的需求中,最大的難點(diǎn)就是需要有五層網(wǎng)元組的嵌套,五層同時(shí)展開時(shí),要求清晰美觀。常規(guī)的分組形狀有圓形、矩形、平行四邊形等,無論哪種形狀,分組多了后,就會(huì)產(chǎn)生審美疲勞。比如,我讓設(shè)計(jì)師mm簡(jiǎn)單地把五層嵌套畫個(gè)圖,它看起來會(huì)是這樣:


           

          我把這個(gè)圖給客戶看了以后,客戶表示希望“結(jié)構(gòu)能夠更加清晰”。那天,魔都大雨傾盆,我抓耳撓腮一個(gè)下午,終于有了一些靈感。

           

          顏色 

          怎樣才能使得結(jié)構(gòu)效果更加清晰?我想到的是用顏色。顏色永遠(yuǎn)是圖形設(shè)計(jì)里面的第一要素。如果分組顏色千篇一律,自然就看不太清楚包含關(guān)系。但是顏色太多五顏六色,顯然也不符合電信UI系統(tǒng)的風(fēng)格。那顏色要如何設(shè)置呢?層層嵌套的分組,層層……叮!你有沒有想到一種蔬菜?

           

            

          (此處哼唱“如果你可以一層一層一層地剝開我的心……”一百遍……)

          這顆大洋蔥看上去層次分明,是因?yàn)樗念伾珡膬?nèi)到外有一定規(guī)律的變化:漸變。說到漸變,又想起最近GF推薦的一枚游戲,大概內(nèi)容是按照顏色的漸變規(guī)律來排列一些方塊。(很無聊有沒有?)

           

           

          不過,前端設(shè)計(jì)中,配色倒是很重要的一個(gè)環(huán)節(jié)。

          總之,想好了用漸變的配色來使嵌套組更清晰后,就大膽地嘗試一下:


          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);  

          數(shù)據(jù)量更大的時(shí)候,看看分組是不是會(huì)更加清晰?


           

          更多顏色

          這個(gè)圖做出來之后,拿給周圍幾個(gè)同事看,大家紛紛表示不錯(cuò),但是似乎有一些死板,不夠生動(dòng)。生動(dòng)。。那就是要活靈活現(xiàn)的,于是我繼續(xù)抓耳撓腮,又想到了一些瓜果蔬菜:

           

           

          果然還是配色不夠明艷啊。我又讓設(shè)計(jì)師mm給找了幾個(gè)色值調(diào)整了一下:




          折角

          有了寫花瓣層疊的感覺,是不是舒服多了?不過,方方正正的組的形狀,還是太死板,缺乏立體感。看到桌子上的一張折了角的白紙,突然有了靈感。

          給方形的組做一個(gè)折角效果,不知效果如何。要做這個(gè)效果,就要重寫group的繪制,自己接管2d繪制了。Group的形狀將不再是一個(gè)矩形,而是一個(gè)切角的矩形。

           

          //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();

          通過繪制一個(gè)帶圓角的矩形并切掉一個(gè)角,stroke到畫布上。看看效果:

           

           

          這里寫圖片描述

           

          再通過增加圓角、切角、增加陰影、設(shè)置不同的邊框線寬,讓分組進(jìn)一步產(chǎn)生“層層遞進(jìn)”的感覺。現(xiàn)在就剩下畫折角的細(xì)節(jié)了。

          折角這里,需要畫一個(gè)被折下來的直角三角形。三角形的顏色,應(yīng)該是“紙”的背面顏色。這里小心定義三角形的形狀,并進(jìn)行填充:


          //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(); 

          效果如下,立體感出來以后,是不是生動(dòng)了很多?

           

          這里寫圖片描述

           

          這里要注意的是,折角的陰影也要設(shè)置,并且填充要使用和邊框相同的顏色,增加“折紙”的立體感。

           

          小細(xì)節(jié)

          折紙效果有了,不過左側(cè)上方略顯空曠,于是利用canvas的2d來練練手,畫個(gè)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();

          運(yùn)行一下,你猜是神馬?

           

          這里寫圖片描述

           

          哈哈,一個(gè)小回形針?biāo)查g躍然紙上了,感覺萌萌噠!為了增加立體感,回形針也是要設(shè)置陰影的,不過偏移不要太大、顏色要淡一些,像這樣:

          這里寫圖片描述

           

           

          適當(dāng)明艷的色彩,加上折角、陰影和小回形針,這回這個(gè)層層嵌套總算是清晰又好看了吧?

          運(yùn)行一下,拖拖拽拽,因?yàn)橹耙呀?jīng)做了不少圖標(biāo)、線條的樣式,所以總體效果還是很不錯(cuò)的!

           

          這里寫圖片描述

          這里寫圖片描述


          后記 

          之前也說,HTML5的canvas,雖然已經(jīng)不是什么新鮮技術(shù)了,但當(dāng)技術(shù)本身不再有壁壘,我們更應(yīng)該注重的是實(shí)際業(yè)務(wù)中的應(yīng)用,比如在畫這種組織結(jié)構(gòu)關(guān)系非常復(fù)雜的拓?fù)鋱D時(shí),如何讓圖形更加清晰、易懂,讓技術(shù)真正落到實(shí)處。如果你有更加好的這類拓?fù)鋱D的解決方案,也可以和我聯(lián)系交流:tw-service@servasoft.com

           


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 延边| 田林县| 大埔县| 横山县| 灌云县| 泗洪县| 嫩江县| 雷山县| 临城县| 阳信县| 南和县| 余姚市| 南陵县| 济宁市| 东乡县| 白玉县| 临澧县| 楚雄市| 温州市| 和硕县| 建瓯市| 巴彦淖尔市| 普格县| 荥阳市| 广东省| 莱阳市| 南投市| 台山市| 高淳县| 镇安县| 五莲县| 右玉县| 江川县| 宣威市| 陵川县| 安图县| 淮滨县| 云阳县| 阿克苏市| 临江市| 常德市|