未加星标

基于HTML5的交互式上海地铁图

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

学了TWaver,对类似拓扑的图形就有了一份敏感,看到就想用TWaver试一试。

比如地铁图。

想到就干,先到网上找幅参考图,最后优中选优选中这一张:


基于HTML5的交互式上海地铁图

先来看看用TWaverhtml5完成的地铁图效果:


基于HTML5的交互式上海地铁图

怎么样,看起来相似度还是很高的吧!

如果您觉得并不够完美,请您不要忽略了一点,这个地铁图中的许多美化和调整是通过程序自动完成的,大大节省了人工成本。更重要的是,它并不是一张死图,而是纯矢量、可交互、有动态效果、无失真缩放的拓扑图!

一、动态显示效果

下面就先来看看它有哪些动态效果吧:

1. 灵活的文本提示

自动鼠标提示,是TWaver的基本功能。每一个网元,不管是节点还是连线,只要设置了name属性,鼠标移入后,默认都会进行弹窗显示。当然,用户也可以定制弹窗显示的内容。比如,我们可以把某个站点首班和末班车的时间显示出来,也可以把换乘信息等显示出来,只需要一个setToolTip就可以了。


基于HTML5的交互式上海地铁图
2. 生动的动态站点

当鼠标移入,站点获得焦点的时候,我们希望站点能有所变化,以给出动态提示。


基于HTML5的交互式上海地铁图

这是通过在注册站点矢量图形时,加入动态判断实现的。以下代码是普通站点的矢量图形:

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; } }); 3. 丰富的动画功能

从上图可以看到,在换乘站图标中,还实现了旋转的动态效果,这对于来说TWaver也很容易,只不过对rotae属性进行了动态改变而已。

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

另外,本例还实现了站点selected和loading的动画效果,方法都是大同小异的。


基于HTML5的交互式上海地铁图
基于HTML5的交互式上海地铁图
二、用户交互功能

交互功能是TWaver的精髓,如果只是为了图画的漂亮,那完全可以选择其他作图工具了。

1. 蛋疼的拖拽回弹

为了判断是不是一张死图,大家往往会下意识地去拖拽站点,看看能不能拖动。既然我们做的不是一张死图,当然要让站点能够拖动。但如果站点会被随便拖走,那么很快整个地铁图就会变得乱七八糟了,所以在松开鼠标后站点必须还能回到原来位置。


基于HTML5的交互式上海地铁图

要说这个功能有什么用,我也只能呵呵了。但闲的蛋疼的时候可以随便玩上几十分钟我也是信的。

2. 合理的缩放功能

既然是矢量图,当然可以实现无失真缩放,而且可以选择不同的缩放模式,还有缩小后文字自动隐藏等贴心小功能。


基于HTML5的交互式上海地铁图
network.setZoomManager(new twaver.vector.MixedZoomManager(network)); network.setMinZoom(0.2); network.setMaxZoom(3); network.setZoomVisibilityThresholds({ label : 0.6, }); 3. 简单的路线展示

连续单击同一站点(注意不是双击),可以将经过此站点的所有线路突出显示出来。加入这个功能纯粹因为简单易做,您完全可以改成其他功能,TWaver表示只要你开心全都OK。


基于HTML5的交互式上海地铁图
4. 复杂的路径规划

连续单击不同的两个站点,则自动规划两站之间的合理路径。这个功能貌似比较实用,但实现起来有一点难度,原谅哥最近时间太紧,例子中竟然没能完整实现。。。


基于HTML5的交互式上海地铁图
5. 实用的电子地图

一张地铁图,即使做的再复杂,功能也是有限的,有时候调用其他软件是扩展功能的一个好办法,比如双击站点后显示站点周围的电子地图。

network.addInteractionListener(function(e){ if(mapDiv){ mapDiv.style.display = 'none'; mapDiv = null; dbclickSta = null; } if(e.kind == 'doubleClickElement' && e.element && e.element.getClassName() == 'twaver.Node' && e.element.getId().length == 6){ dbclickSta = e.element; if(dbclickSta.getClient('coord')){ coord = dbclickSta.getClient('coord'); mapDiv = createMap(coord, e.event); }else{ dbclickSta.setClient('dbclick', true); var lineName = json.lines[dbclickSta.getId().substr(0,3)].name; var stationName = dbclickSta.getName(); var addr = "上海市地铁" + lineName + stationName; var geocoder = new qq.maps.Geocoder(); geocoder.getLocation(addr); geocoder.setComplete(function(result) { coord =result.detail.location; mapDiv = createMap(coord, e.event); dbclickSta.setClient('dbclick', false); }); geocoder.setError(function() { var coord = {"lat":31.188,"lng":121.425}; mapDiv = createMap(coord, e.event); }); } } });

在电子地图中定位站点,可以通过在站点数据中加入站点的经纬度,也可以通过站点关键字在电子地图中直接查询。


基于HTML5的交互式上海地铁图

当然,TWaver能实现交互功能不仅仅是例子中展示的这一点点,只有你想不到,没有你做不到。你完全可以赋予地铁图更强大的功能,也可以举一反三做出高铁图、交通图等等类似实例。

三、程序设计简介

这样一个小例子设计起来其实并没有什么复杂的,整理好数据,创建站点、路径,做些美化工作,添加点互动功能,就齐活了。

1. 整理地铁数据

俗话说兵马未动粮草先行,没有数据再好的创意也白搭。数据格式,自然首选javascript原生支持的json文件,直观方便。

首先要确定数据结构,一个好的结构设计会让后面的编程轻松方便。本例按照站点、线路、杂项三大项来组织数据。站点和线路分别统计的优点是将来方便对其进行遍历、查询等操作。

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

当然,大家看到网上例子,有的会把label也单独出来,这样虽然可以灵活定义label 的位置,但却使得站点和label两张皮,而且也增加了数据采集的工作量。TWaver有对label丰富的自定义功能,所以完全没有必要将label单拎出去,只需给其一个位置属性就可以了。

2. 创建站点线路

首先是读取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(staIdin 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(lineIdin json.lines) { …… for(staSnin 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的位置,否则站点名称会显示的很乱。高手应该可以通过程序自动判断站点周围控件,智能调整label的显示位置,可惜我没做到,还是通过手动在数据中加入label位置信息的办法进行人工调整。

最后再设计一下站点图标,一张原始的地铁图就呈现出来了。


基于HTML5的交互式上海地铁图

可能有的地铁图就到此为止了,基本的示意功能已经具备了嘛。但追求完美的TWaver怎么可能忍受,起码线路走向要规整一些,不能两个站点间直线一连就完事了。

3. 添加路线拐点

本例通过智能添加拐点,使线路只保留了横平竖直和正斜的走向,以达到整齐美观的效果。可能看起来与参考图稍稍有些不同,主要因为各路段基本只添加了一个拐点,这样做既大大简化了程序,又基本保证了图形的美观度。


基于HTML5的交互式上海地铁图

当然为了提高程序的灵活性,比如应对磁悬浮线这种特殊情况,也加入了人工拐点的添加功能。为了方便与智能拐点混用的情况下的判断和实现,人工拐点被设成一个隐形的节点。

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

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:基于HTML5的交互式上海地铁图
本站链接:http://www.codesec.net/view/480358.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(41)