自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HTML5,不只是看上去很美(第四彈:可交互地鐵線路圖)

開發(fā) 前端
最近特別忙,承蒙大伙關照,3D機房的項目一個接著一個,領了一幫小弟,搞搞傳幫帶,烏飛兔走,轉(zhuǎn)眼已經(jīng)菊黃蟹肥……有個小弟很不錯,勤奮好學,很快就把API都摸透了,國慶幾天自己折騰著做了個HTML5的魔都的地鐵線路圖,能拖能拽的,還和電子地圖做了交互。哥決定把小弟的成果納入“HTML5,不只是看上去很美”系列,以示鼓勵。

前言

最近特別忙,承蒙大伙關照,3D機房的項目一個接著一個,領了一幫小弟,搞搞傳幫帶,烏飛兔走,轉(zhuǎn)眼已經(jīng)菊黃蟹肥……有個小弟很不錯,勤奮好學,很快就把API都摸透了,國慶幾天自己折騰著做了個HTML5的魔都的地鐵線路圖,能拖能拽的,還和電子地圖做了交互。哥決定把小弟的成果納入“HTML5,不只是看上去很美”系列,以示鼓勵(P.S. 其實還挺有壓力的,后浪推前浪,新人趕舊人。我們這些老鳥也得注意,免得讓00后給搶了飯碗)

效果圖對比

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

再來看看小弟做的:

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

文本提示彈彈彈

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

站點圖標變變變

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

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

  1. twaver.Util.registerImage('station',{ 
  2.     w: linkWidth*1.6, 
  3.     h: linkWidth*1.6, 
  4.     v: function (data, view) { 
  5.         var result = []; 
  6.         if(data.getClient('focus')){ 
  7.             result.push({ 
  8.                 shape: 'circle'
  9.                 r: linkWidth*0.7, 
  10.                 lineColor:  data.getClient('lineColor'), 
  11.                 lineWidth: linkWidth*0.2, 
  12.                 fill: 'white'
  13.             }); 
  14.             result.push({ 
  15.                 shape: 'circle'
  16.                 r: linkWidth*0.2, 
  17.                 fill:  data.getClient('lineColor'), 
  18.             }); 
  19.         }else
  20.             result.push({ 
  21.                 shape: 'circle'
  22.                 r: linkWidth*0.6, 
  23.                 lineColor: data.getClient('lineColor'), 
  24.                 lineWidth: linkWidth*0.2, 
  25.                 fill: 'white'
  26.             }); 
  27.         } 
  28.         return result; 
  29.     } 
  30. });  

動畫效果拽拽拽

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

  1. twaver.Util.registerImage('rotateArrow', { 
  2.         w: 124, 
  3.         h: 124, 
  4.         v: [{ 
  5.             shape: 'vector'
  6.             name'doubleArrow'
  7.             rotate: 360, 
  8.             animate: [{ 
  9.                 attr: 'rotate'
  10.                 to: 0, 
  11.                 dur: 2000, 
  12.                 reverse: false
  13.                 repeat: Number.POSITIVE_INFINITY 
  14.             }] 
  15.         }] 
  16.     });  

當然這對于TWaver來說也很容易,只不過對rotate屬性進行了動態(tài)改變而已。

另外,在單擊和雙擊站點時,還實現(xiàn)了selected和loading的動畫效果,值得點贊!

混合縮放炫炫炫

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

代碼也不復雜:

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

交互功能用起來

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

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

連續(xù)單擊同一站點

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

雙擊站點

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

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

數(shù)據(jù)文件的整理

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

  1.         "stations":{ 
  2.             "l01s01":{ }, 
  3.             ………… 
  4.         } 
  5.         "lines":{ 
  6.             "l01":{……}, 
  7.             ………… 
  8.         } 
  9.         "sundrys":{ 
  10.             "railwaystationshanghai":{……}, 
  11.             ………… 
  12.         } 
  13.     }  

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

  1. "l01s01":{ 
  2.        "id":"l01s01"
  3.        "name":"莘莊"
  4.        "loc":{"x":419,"y":1330}, 
  5.        "label":"bottomright.bottomright"
  6.    }, 
  7.    …………  

站點路線的創(chuàng)建

首先是讀取json文件的數(shù)據(jù)。

  1. function loadJSON(path,callback){ 
  2.         var xhr = new XMLHttpRequest(); 
  3.         xhr.onreadystatechange = function(){ 
  4.             if (xhr.readyState === 4) { 
  5.                 if (xhr.status === 200) { 
  6.                    dataJson = JSON.parse(xhr.responseText); 
  7.                    callback && callback(); 
  8.                } 
  9.            } 
  10.        }; 
  11.        xhr.open("GET", path, true); 
  12.        xhr.send(); 
  13.     }  

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

  1. function init(){ 
  2.         loadJSON("shanghaiMetro.json"function(){ 
  3.             initNetwork(dataJson); 
  4.             initNode(dataJson); 
  5.         }); 
  6.     }  

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

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

再對數(shù)據(jù)文件中的各條線路下的所有站點進行遍歷,在站點間依次創(chuàng)建Link。

  1. for(lineId in json.lines) { 
  2.         …… 
  3.         for(staSn in line.stations) { 
  4.             …… 
  5.             var link = new twaver.Link(linkId,prevSta,staNode); 
  6.             link.s('link.color', line.color); 
  7.             link.s('link.width', linkWidth); 
  8.             link.setToolTip(line.name); 
  9.             box.add(link); 
  10.         } 
  11.     }  

再對label位置進行調(diào)整,否則站點名稱會顯示的很亂。小弟是通過在原始數(shù)據(jù)中手動加入位置信息來實現(xiàn)的,稍顯笨了一點,應該可以通過程序自動判斷站點周圍空間來進行智能調(diào)整。

最后再加入圖標,一張原始的地鐵圖就呈現(xiàn)出來了。

路線拐點的添加

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

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

  1. var createTurnSta = function(line, staSn){ 
  2.     staTurn = new twaver.Node(staSn); 
  3.     staTurn.setImage(); 
  4.     staTurn.setClient('lineColor',line.color); 
  5.     staTurn.setClient('lines',[line.id]); 
  6.     var loc = line.stations[staSn]; 
  7.     staTurn.setClient('location',loc); 
  8.     box.add(staTurn); 
  9.     return staTurn; 
  10.  

接點位置的調(diào)整

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

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

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

  1. var azimuth = { 
  2.     bb: {x: 0, y: linkWidth*zoom/2}, 
  3.     tt: {x: 0, y: -linkWidth*zoom/2}, 
  4.     rr: {x: linkWidth*zoom/2, y: 0}, 
  5.     ll: {x: -linkWidth/2, y: 0}, 
  6.     br: {x: linkWidth*zoom*0.7/2, y: linkWidth*zoom*0.7/2}, 
  7.     bl: {x: -linkWidth*zoom*0.7/2, y: linkWidth*zoom*0.7/2}, 
  8.     tr: {x: linkWidth*zoom*0.7/2, y: -linkWidth*zoom*0.7/2}, 
  9.     tl: {x: -linkWidth*zoom*0.7/2, y: -linkWidth*zoom*0.7/2}, 
  10.     BB: {x: 0, y: linkWidth*zoom}, 
  11.     TT: {x: 0, y: -linkWidth*zoom}, 
  12.     RR: {x: linkWidth*zoom, y: 0}, 
  13.     LL: {x: -linkWidth, y: 0}, 
  14.     BR: {x: linkWidth*zoom*0.7, y: linkWidth*zoom*0.7}, 
  15.     BL: {x: -linkWidth*zoom*0.7, y: linkWidth*zoom*0.7}, 
  16.     TR: {x: linkWidth*zoom*0.7, y: -linkWidth*zoom*0.7}, 
  17.     TL: {x: -linkWidth*zoom*0.7, y: -linkWidth*zoom*0.7} 
  18. };  

介紹到這里就結(jié)束了,雖然是個小例子,實在是但美觀性和實用性都還過得去,小弟花了心思去做,其實稍加改造就可以做出高鐵圖、公交圖、運行圖等應用。設想一下,如果能用在軌道交通列控中心大屏監(jiān)控里,是多么炫酷。說到這,又想起了前兩天云棲大會上剛看到的杭州城市數(shù)據(jù)大腦,不知何時,哥也能參與一把那樣的項目呢?可視化,哥的強項……

最后,想要看程序,或者想玩“地鐵拖拖樂”的各位,都可以給我留言和發(fā)郵件:tw-service@servasoft.com。

 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2022-07-05 11:17:46

零信任安全技術網(wǎng)絡安全

2012-09-19 13:47:53

HTML5

2012-11-14 09:48:57

HBase大數(shù)據(jù)

2011-12-08 08:58:28

JavaScript

2014-07-09 16:58:38

WIFI

2019-12-02 12:50:52

LiFiWiFi通信網(wǎng)絡

2012-11-14 08:57:29

HBase

2013-01-25 11:17:17

Gartner大數(shù)據(jù)傳感器

2009-08-03 14:09:13

SAP中國真相SAP

2010-06-25 09:19:18

云計算應用

2024-03-26 13:03:16

NettyJavaNIO

2024-10-08 15:16:23

SQL地鐵換乘數(shù)據(jù)庫

2015-07-21 14:53:48

HTML5趨勢

2012-11-27 12:31:11

BYOD銳捷網(wǎng)絡

2017-03-25 21:13:38

JavaScript排序

2011-05-16 10:10:51

2020-09-17 17:46:20

Python地鐵線路圖

2013-04-25 13:58:15

編程

2021-11-05 11:17:45

互聯(lián)網(wǎng)996大廠

2010-08-05 09:29:08

jQuery
點贊
收藏

51CTO技術棧公眾號