<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    TWaver - 專注UI技術

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

    前言

     

    最近特別忙,承蒙大伙關照,3D機房的項目一個接著一個,領了一幫小弟,搞搞傳幫帶……有個小弟很不錯,勤奮好學,很快就把API都摸透了,自己折騰著做了個HTML5的魔都的地鐵線路圖,能拖能拽的,還和電子地圖做了交互。哥決定把小弟的成果給大家展示一下。

     

    效果圖對比

     

    網上的地鐵圖還是很多的,小弟選了這張比較新的做參考。想當年哥來魔都打拼時,圖上可就一紅一綠打個叉……暴露年齡的話不多說,看圖:

    再來看看小弟做的:

    我是一眼看不出區別,但這可不是一張效果圖,而是一個新手僅用了幾天做出來的東西,而且里面許多美化和調整是通過程序自動完成的,這就不容易了。更重要的是,它并不是一張死圖,而是純矢量、可交互、有動態效果、無失真縮放的拓撲圖!我們先簡單看一下交互效果,后面可以詳細說說代碼的實現。

     

    文本提示彈彈彈

     

    首先,把鼠標移到站點、路段、圖標等位置,都會有文本提示彈出,這個比較基本,百度家的就有,小弟也就放了比較簡單的彈出內容。如果加上基本介紹啊、相關提示啊、周邊信息啊……要是加上廣告,就可以賺錢了……反正什么都可以加嘛,就是一個setToolTip命令而已。

     

     

    站點圖標變變變

     

    當鼠標移到站點上時,站點圖標做了放大效果,這個效果很貼心,看了下百度家,用的是發光效果。

     

     

    實現的方法也很簡便,就是在注冊站點矢量圖形時,加入了動態判斷。以下注冊普通站點矢量圖形的代碼:


    twaver.Util.registerImage('station',{
        w: linkWidth
    *1.6,
        h: linkWidth
    *1.6,
        v: function (data, view) {
            var result 
    = [];
            
    if(data.getClient('focus')){
                result.push({
                    shape: 
    'circle',
                    r: linkWidth
    *0.7,
                    lineColor:  data.getClient(
    'lineColor'),
                    lineWidth: linkWidth
    *0.2,
                    fill: 
    'white',
                });
                result.push({
                    shape: 
    'circle',
                    r: linkWidth
    *0.2,
                    fill:  data.getClient(
    'lineColor'),
                });
            }
    else{
                result.push({
                    shape: 
    'circle',
                    r: linkWidth
    *0.6,
                    lineColor: data.getClient(
    'lineColor'),
                    lineWidth: linkWidth
    *0.2,
                    fill: 
    'white',
                });
            }
            
    return result;
        }
    });

    動畫效果拽拽拽

     

    從上圖還可以看到,在換乘站圖標中,除了增加了顏色,還實現了旋轉效果。這個就秒殺百度家了。 來看代碼:


    twaver.Util.registerImage('rotateArrow', {
        w: 
    124,
        h: 
    124,
        v: [{
            shape: 
    'vector',
            name: 
    'doubleArrow',
            rotate: 
    360,
            animate: [{
                attr: 
    'rotate',
                to: 
    0,
                dur: 
    2000,
                reverse: 
    false,
                repeat: Number.POSITIVE_INFINITY
            }]
        }]
    });

    當然這對于TWaver來說也很容易,只不過對rotate屬性進行了動態改變而已。 另外,在單擊和雙擊站點時,還實現了selected和loading的動畫效果,值得點贊!

     

     

     

    混合縮放炫炫炫

     

    無失真縮放是矢量圖的先天優勢,小弟也掌握得爐火純青,把TWaver的混合縮放模式用到極致,還有縮放比例控制、文字自動隱藏等小功能,方便訂制。

     

     

    代碼也不復雜:


    network.setZoomManager(new twaver.vector.MixedZoomManager(network));
    network.setMinZoom(
    0.2);
    network.setMaxZoom(
    3);
    network.setZoomVisibilityThresholds({
        label : 
    0.6,
    });

    交互功能用起來

     

    小弟很自豪地給我介紹這個功能:圖標可以自由拖動,松開后會自動彈回。哥問小弟這有什么用,他一本正經地說:證明圖是活的!

     

     

     

    好吧你贏了,雖然是個沒什么卵用的功能,但閑的蛋疼的時候可以隨便玩上幾十分鐘我也是信的。

     

    連續單擊同一站點

     

    連續單擊同一站點(注意不是雙擊),可以將經過此站點的所有線路突出顯示出來。小弟說加入這個功能純粹因為簡單易做,我……竟然表示非常理解,誰年輕時沒耍過這類輕松又討好的小招數呢?

     

     

     

    雙擊站點

     

    雙擊站點,竟然彈出了本站周邊的電子地圖!知道引入他山之玉,看來小子可教啊。我發現他的定位方法,有的是用經緯度,有的是關鍵詞查詢。小弟狡黠地說,開始是人工查每個站點經緯度的,干了一段兒發現太麻煩,后來改路子了。馬大大說的,懶人改變世界,我服!

     

     

     

    最后來八一八程序設計的思路吧,小弟是棵好苗子,能做出那么像樣的程序,必然是深思熟慮過的。不想再聽我啰嗦的朋友,也可以直接發郵件給我,tw-service@servasoft.com,來鑒賞下小弟的成果。

     

    數據文件的整理

     

    數據格式,選擇了JavaScript原生支持的json文件,直觀方便。 數據結構,按照站點、線路、雜項三大塊來組織,結構清晰,利于遍歷、查詢等操作。

     

    {
        
    "stations":{
            
    "l01s01":{ },
            …………
        }
        
    "lines":{
            
    "l01":{……},
            …………
        }
        
    "sundrys":{
            
    "railwaystationshanghai":{……},
            …………
        }
    }

    命名比較規范,通過名字就可以看出基本信息(例如“l01s01”就是1號線第1個站點),甚至直接利用名字就可以進行查詢和遍歷。

        "l01s01":{
            
    "id":"l01s01",
            
    "name":"莘莊",
            
    "loc":{"x":419,"y":1330},
            
    "label":"bottomright.bottomright",
        },
        …………

    站點路線的創建

     

    首先是讀取json文件的數據。


        function loadJSON(path,callback){
            var xhr 
    = new XMLHttpRequest();
            xhr.onreadystatechange 
    = function(){
                
    if (xhr.readyState === 4) {
                    
    if (xhr.status === 200) {
                       dataJson 
    = JSON.parse(xhr.responseText);
                       callback 
    && callback();
                   }
               }
           };
           xhr.open(
    "GET", path, true);
           xhr.send();
        }

    因為讀取文件是一個異步的過程,所以要程序的展開都要放在文件讀取函數的內部。

        function init(){
            loadJSON(
    "shanghaiMetro.json", function(){
                initNetwork(dataJson);
                initNode(dataJson);
            });
        }

    只要通過對站點進行一次遍歷,車站的建立就完成了。

        for(staId in json.stations){
            var station 
    = json.stations[staId];
            staNode 
    = new twaver.Node({
                id: staId,
                name: station.name,
                image:
    'station',
            });
            staNode.s(
    'label.color','rgba(99,99,99,1)');
            staNode.s(
    'label.font','12px 微軟雅黑');
            staNode.s(
    'label.position',station.label);
            staNode.setClient(
    'location',station.loc);
            box.add(staNode);
        }

    再對數據文件中的各條線路下的所有站點進行遍歷,在站點間依次創建Link。

        for(lineId in json.lines) {
            ……
            
    for(staSn in line.stations) {
                ……
                var link 
    = new twaver.Link(linkId,prevSta,staNode);
                link.s(
    'link.color', line.color);
                link.s(
    'link.width', linkWidth);
                link.setToolTip(line.name);
                box.add(link);
            }
        }

    再對label位置進行調整,否則站點名稱會顯示的很亂。小弟是通過在原始數據中手動加入位置信息來實現的,稍顯笨了一點,應該可以通過程序自動判斷站點周圍空間來進行智能調整。 最后再加入圖標,一張原始的地鐵圖就呈現出來了。

     

     

     

    路線拐點的添加

     

    基本的示意功能已經具備了,這里,小弟讓我很欣賞的一點是沒有就此停止,而是進一步做了調整,使線路只保留了橫平豎直和正斜的走向,以達到整齊美觀的效果。可能看起來與參考圖稍稍有些不同,主要因為各路段基本只添加了一個拐點,這樣做既大大簡化了程序,又基本保證了圖形的美觀度。想遠一點,做多一點,是塊做產品的好料子。

     

     

    當然為了提高程序的靈活性,應對必須添加兩個或以上拐點的情況,也使用了人工拐點的手段。不過這里人工拐點被設成一個隱形的節點,可能利于智能拐點的判斷,但也有可能在路線操作時造成混亂。如何處理更好還可以進一步推敲。


    var createTurnSta = function(line, staSn){
        staTurn 
    = new twaver.Node(staSn);
        staTurn.setImage();
        staTurn.setClient(
    'lineColor',line.color);
        staTurn.setClient(
    'lines',[line.id]);
        var loc 
    = line.stations[staSn];
        staTurn.setClient(
    'location',loc);
        box.add(staTurn);
        
    return staTurn;
    }

    接點位置的調整

     

    大家可以看到,并不是所有路段都直接連入站點中心,在許多情況下必須要進行偏移。


    var createFollowSta = function(json, line, staNode, staId){
        staFollow 
    = new twaver.Follower(staId);
        staFollow.setImage();
        staFollow.setClient(
    'lineColor',line.color);
        staFollow.setClient(
    'lines',[line.id]);
        staFollow.setHost(staNode);
        var az 
    = azimuth[staId.substr(6,2)];
        var loc0 
    = json.stations[staId.substr(0,6)].loc;
        var loc 
    = {x:loc0.x+az.x, y:loc0.y+az.y};
        staFollow.setClient(
    'location',loc);
        box.add(staFollow);
        
    return staFollow;
    }

     

     

    小弟采取了虛擬節點的辦法,就是在站點的旁邊,添加一個Follower(但并不顯示出來),讓并行的不同線路連接到不同的Follower上。通過調整Follower的位置,來實現線路與站點連接點的控制。


    var azimuth = {
        bb: {x: 
    0, y: linkWidth*zoom/2},
        tt: {x: 
    0, y: -linkWidth*zoom/2},
        rr: {x: linkWidth
    *zoom/2, y: 0},
        ll: {x: 
    -linkWidth/2, y: 0},
        br: {x: linkWidth
    *zoom*0.7/2, y: linkWidth*zoom*0.7/2},
        bl: {x: 
    -linkWidth*zoom*0.7/2, y: linkWidth*zoom*0.7/2},
        tr: {x: linkWidth
    *zoom*0.7/2, y: -linkWidth*zoom*0.7/2},
        tl: {x: 
    -linkWidth*zoom*0.7/2, y: -linkWidth*zoom*0.7/2},
        BB: {x: 
    0, y: linkWidth*zoom},
        TT: {x: 
    0, y: -linkWidth*zoom},
        RR: {x: linkWidth
    *zoom, y: 0},
        LL: {x: 
    -linkWidth, y: 0},
        BR: {x: linkWidth
    *zoom*0.7, y: linkWidth*zoom*0.7},
        BL: {x: 
    -linkWidth*zoom*0.7, y: linkWidth*zoom*0.7},
        TR: {x: linkWidth
    *zoom*0.7, y: -linkWidth*zoom*0.7},
        TL: {x: 
    -linkWidth*zoom*0.7, y: -linkWidth*zoom*0.7}
    };

    介紹到這里就結束了,雖然是個小例子,但美觀性和實用性都還過得去,小弟花了心思去做,其實稍加改造就可以做出高鐵圖、公交圖、運行圖等應用。設想一下,如果能用在軌道交通列控中心大屏監控里,是多么炫酷。說到這,又想起了前段時間云棲大會上剛看到的杭州城市數據大腦,不知何時,哥也能參與一把那樣的項目呢?可視化,哥的強項…… 最后,想要看程序,或者想玩“地鐵拖拖樂”的各位,都可以給我留言和發郵件:tw-service@servasoft.com

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲邪恶天堂影院在线观看| 国产精品亚洲视频| 亚洲gv猛男gv无码男同短文| 国产亚洲漂亮白嫩美女在线| 免费高清av一区二区三区| 亚洲成综合人影院在院播放| 七色永久性tv网站免费看| 亚洲国产美女精品久久久久∴| 中文字幕在线观看免费| 亚洲国产另类久久久精品黑人| 久久久WWW免费人成精品| 国产亚洲精品AA片在线观看不加载 | 亚洲毛片无码专区亚洲乱| 在线a免费观看最新网站| 亚洲毛片免费视频| 免费中文熟妇在线影片 | 麻豆91免费视频| 亚洲高清偷拍一区二区三区| 成人一级免费视频| 亚洲日韩精品一区二区三区| 最近免费字幕中文大全视频| 亚洲一区二区三区在线网站| 成人永久福利免费观看| 一个人看的hd免费视频| 亚洲av女电影网| 久久久久久久久免费看无码| 国产亚洲精品美女| 亚洲精品高清国产一线久久| 久久国产精品成人片免费| 中文字幕乱码亚洲精品一区| 国产一区在线观看免费| 人人揉揉香蕉大免费不卡| 亚洲中文久久精品无码1| 免费看国产精品麻豆| 国产猛男猛女超爽免费视频| 亚洲午夜电影在线观看| 国产一级特黄高清免费大片| 国内精品免费视频精选在线观看| 亚洲国产中文在线视频| 亚洲国产香蕉人人爽成AV片久久| 小草在线看片免费人成视久网|