• 技术文章 >web前端 >H5教程

    基于HTML5制作在线上海地铁图

    2016-05-17 09:07:59原创1062
    某市政项目要用到地铁图,展示上海地铁站点以及相关信息流,尝试使用HTML5技术来实现,自己折腾有点慢,找到一个HTML5的图形组件-Qunee for HTML5,简单学习一下,就可以很好的解决这类需求,做出优美的展现,下面以上海2012地铁图为例,效果如下:


    示例讲解

    首先需要解决数据问题,可以从维基百科或者上海地铁官网中获取,不过也免不了人工,要达到良好的显示效果,需要不只要记录站点的位置,还需要设置文本标签的理想位置,有时为了避免文字叠加,需要设置旋转角度……总之事在人为,想想办法,最终解决了数据问题,再加上Qunee图形组件的强大展示效果,做出来可以交互的在线地铁图

    数据格式

    采用JSON格式数据,分三种类型:文本标签、站点、地铁线

    总的结构如下:

    1. {
    2. "labels" : [ ... ],
    3. "stations" : [ ... ],
    4. "lines" : [ ... ]
    5. }
    复制代码

    文本标签数据

    包含坐标和文字信息,如果文字需要旋转,则会增加”rotate”属性,下面是“莘庄”文本标签信息
    1. {
    2. "text" : "莘庄",
    3. "x" : 883.591,
    4. "y" : 1625.695
    5. }
    复制代码

    文字与节点旋转效果


    站点数据

    包含坐标、旋转角度以及编号信息,下面是“莘庄”站的信息

    1. {
    2. "id" : 5,
    3. "x" : 869.8513512641732,
    4. "y" : 1597.6559686949402,
    5. "rotate" : 0.7853981633974483
    6. }
    复制代码

    地铁线数据

    包含名称,颜色,以及经过的站点编号

    1. {
    2. "name" : "1",
    3. "color" : "#e52035",
    4. "stations" : [64, 70, 67, 71, 72, 65, 69, 73, 66, 68, 63, 62, 22, 61, 60, {"id": 21, "yOffset": 0.5}, 59, {"id": 18, "yOffset": -0.5}, 17, 58, 14, 7, 57, 6,
    5. 56, 44, 47, 5]
    6. }
    复制代码

    对于特殊情况,比如两条地铁线共用一条线路的情况,会出现两条线重合,为了避免这种情况,还可以指定站点横向偏移量,比如上面一号线中的如下数据

    1. {"id": 21, "yOffset": 0.5}
    复制代码

    因为上海地铁三号线与四号线共用线路较多,所以这种处理更加明显

    三号线数据

    1. {
    2. "name" : "3",
    3. "color" : "#f9d300",
    4. "stations" : [6, 95, 96, 97, {"id":12,"yOffset":0.5}, {"id":11,"yOffset":0.5}, {"id":8,"yOffset":0.5}, {"id":9,"yOffset":0.5},
    5. {"id":10,"yOffset":0.5}, {"id":25,"yOffset":0.5}, {"id":26,"yOffset":0.5}, {"id":238,"yOffset":0.5}, {"id":22,"yOffset":-0.5}, {"id":27,"yOffset":-0.5},
    6. 98, 99, 100, 101, 104, 105, 107, 108, 109, 106, 110, 111]
    7. }
    复制代码

    地铁共线效果

    创建图元

    数据需要转换成qunee图元对象,三种类型分别对应三个创建函数

    创建文本标签
    1. function createText(name, x, y, rotate){
    2. var text = graph.createNode(name, x, y);
    3. if(rotate){
    4. text.rotate = rotate;
    5. }
    6. text.zIndex = 20;
    7. text.image = null;
    8. text.setStyle(Q.Styles.BACKGROUND_COLOR, Q.toColor(0x88FFFFFF));
    9. text.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM);
    10. text.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE);
    11. text.setStyle(Q.Styles.LABEL_PADDING, PADDING);
    12. return text;
    13. }
    复制代码

    创建站点

    1. function createStation(station){
    2. var node = graph.createNode(null/**station.name*/, station.x, station.y);
    3. node.stationId = station.id;
    4. node.setStyle(Q.Styles.LABEL_FONT_SIZE, 10);
    5. node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.CENTER_MIDDLE);
    6. node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE);
    7. node.zIndex = 10;
    8. if(station.rotate){
    9. node.image = roundRect;
    10. node.rotate = station.rotate;
    11. }else{
    12. node.image = circle;
    13. }
    14. node.setStyle(Q.Styles.SHAPE_FILL_COLOR, "#FFF");
    15. node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, "#000");
    16. return node;
    17. }
    复制代码

    创建地铁线

    createLine(…)函数用于创建地铁线,使用了节点类型图元,并设置节点主体为路径,函数updateLine(…)用于从站点信息自动生成线路路径

    1. function createLine(line){
    2. var stations = line.stations;

    3. var node = graph.createNode(line.name);
    4. node.stations = stations;
    5. node.movable = false;
    6. node.setStyle(Q.Styles.LABEL_FONT_SIZE, 50);
    7. node.setStyle(Q.Styles.LABEL_COLOR, line.color);
    8. node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM);
    9. node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.LEFT_TOP);
    10. node.setStyle(Q.Styles.LAYOUT_BY_PATH, true);
    11. node.anchorPosition = null;
    12. node.setStyle(Q.Styles.SHAPE_STROKE, size);
    13. node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, line.color);

    14. updateLine(node, true);
    15. return node;
    16. }
    复制代码
    1. function updateLine(line, addListener){
    2. var path = new Q.Path();
    3. line.image = path;

    4. var stations = line.stations;
    5. var first = true;
    6. Q.forEach(stations, function(s){
    7. var station = getStation(s.id || s);
    8. if(!station){
    9. return;
    10. }
    11. if(addListener){
    12. addLocationChangeListener(station.stationId, line);
    13. }
    14. var location = station.location;
    15. var x = location.x, y = location.y;
    16. if(s.yOffset){
    17. var offset = s.yOffset * size;
    18. var rotate = station.rotate || 0;
    19. var sin = Math.sin(rotate);
    20. var cos = Math.cos(rotate);
    21. x += cos * offset;
    22. y += sin * offset;
    23. }
    24. if(first){
    25. first = false;
    26. path.moveTo(x, y);
    27. }else{
    28. path.lineTo(x, y);
    29. }
    30. })
    31. }
    复制代码

    交互处理

    增加交互处理,监听站点拖动事件,保持地铁路线跟随站点位置变化

    1. graph.interactionDispatcher.addListener(function(evt){
    2. if(evt.kind != Q.InteractionEvent.ELEMENT_MOVING){
    3. return;
    4. }
    5. var datas = evt.datas;

    6. Q.forEach(datas, function(data){
    7. if(!data.stationId){
    8. return;
    9. }
    10. var listeners = stationLocationChangeListeners[data.stationId];
    11. if(listeners){
    12. for(var l in listeners){
    13. updateLine(listeners[l]);
    14. }
    15. }
    16. });
    17. });
    复制代码

    在线示例

    来源:http://blog.chinaunix.net/uid-29563534-id-4171575.html

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:HTML教程:如何设置Iframe自适应高度 下一篇:JavaScript中的原型和继承
    PHP编程就业班

    相关文章推荐

    • html5离线存储有哪些• 深入解析asp.net中mvc4自定义404页面(分享)• h5新增标签audio与video的使用• 你值得了解的HTTP缓存机制(代码详解)• 使用HTML5 SVG绘制各种雪花图案

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网