基于 HTML5 Canvas实现 的交互式地铁线路图分享!

前言

前两天在 echarts 上寻找灵感的时候,看到了很多有关地图类似的例子,地图定位等等,但是好像就是没有地铁线路图,就自己花了一些时间捣鼓出来了这个交互式地铁线路图的 Demo,地铁线路上的点是在网上随便下载了一个,这篇文章记录自己的一些收获(毕竟我还是个菜鸟)以及代码的实现,希望能够帮到一些朋友。当然,如果有什么意见的可以直接跟我说,大家一起交流才会进步。

效果图

基于 HTML5 Canvas实现 的交互式地铁线路图 

https://www.hightopo.com/demo/subway/index.html

地图稍微内容有点多,要全部展示,字显得有点小了,但是没关系,可以按照需求放大缩小,字体和绘制的内容并不会失真,毕竟都是用矢量绘制的~

界面生成

底层的 div 是通过 ht.graph.GraphView 组件生成的,然后就可以利用 HT for Web 提供好的方法,调用 canvas 画笔随便绘制就好,先来看看怎么生成底层 div:
 

  var dm = new ht.DataModel();//数据容器  var gv = new ht.graph.GraphView(dm);//拓扑组件  gv.addToDOM();//将拓扑图组件添加进body中

addToDOM 函数声明如下:

  addToDOM = function(){         var self = this,          view = self.getView(),             style = view.style;      document.body.appendChild(view); //将组件底层div添加到body中                 style.left = '0';//默认组件是绝对定位,所以要设置位置      style.right = '0';      style.top = '0';      style.bottom = '0';            window.addEventListener('resize', function () { self.iv(); }, false); //窗口变化事件             }

现在我就可以在这个 div 上乱涂乱画了~首先我获取下载好的地铁线路图上的点,我将它们放在 subway.js 中,这个 js 文件全部都是下载的内容,我没有做其他的改动,主要是将这些点根据线路来分分配添加到数组中,比如:

  mark_Point13 = [];//线路 数组内包含线路的起点和终点坐标以及这条线路的名称  t_Point13 = [];//换成站点 数组内包含线路中的换乘站点坐标以及换成站点名称  n_Point13 = [];//小站点 数组内包含线路中的小站点坐标以及小站点名称  mark_Point13.push({ name: '十三号线', value: [113.4973,23.1095]});   mark_Point13.push({ name: '十三号线', value: [113.4155,23.1080]});   t_Point13.push({ name: '鱼珠', value: [113.41548,23.10547]});   n_Point13.push({ name: '裕丰围', value: [113.41548,23.10004]}); 

接下来来描绘地铁线路,我声明了一个数组 lineNum,用来装 js 中所有的地铁线路的编号,以及一个 color 数组,用来装所有的地铁线的颜色,这些颜色的 index 与 lineNum 中地铁线编号的 index 是一一对应的:

  var lineNum = ['1', '2', '3', '30', '4', '5', '6', '7', '8', '9', '13', '14', '32', '18', '21', '22', '60', '68'];  var color = ['#f1cd44', '#0060a1', '#ed9b4f', '#ed9b4f', '#007e3a', '#cb0447', '#7a1a57', '#18472c', '#008193', '#83c39e', '#8a8c29', '#82352b', '#82352b', '#09a1e0', '#8a8c29', '#82352b', '#b6d300', '#09a1e0'];

接着遍历 lineNum,将 lineNum 中的元素和颜色传到 createLine 函数中,根据这两个参数来绘制地铁线路以及配色,毕竟 js 文件中的命名方式也是有规律的,哪一条线路,则命名后面一定会加上对应的数字,所以我们只需要将字符串与这个编号结合即可获得 js 中对应的数组了:

  let lineName = 'Line' + num;  let line = window[lineName];  createLine 的定义也非常简单,我的代码设置了不少的样式,所以看起来有点多。创建一个 ht.Polyline 管线,我们可以通过 polyline.addPoint() 函数向这个变量中添加具体的点,通过 setSegments 可以设置点的连接方式。  function createLine(num, color) {//绘制地图线      var polyline = new ht.Polyline();//多边形 管线      polyline.setTag(num);//设置节点tag标签,作为唯一标示      if(num === '68') polyline.setToolTip('A P M');//设置提示信息       else if(num === '60') polyline.setToolTip('G F');       else polyline.setToolTip('Line' + num);      if(color) {          polyline.s({//s 为 setStyle 的简写,设置样式              'shape.border.width': 0.4,//设置多边形的边框宽度              'shape.border.color': color,//设置多边形的边框颜色              'select.width': 0.2,//设置选中节点的边框宽度              'select.color': color//设置选中节点的边框颜色          });      }      let lineName = 'Line' + num;      let line = window[lineName];      for(let i = 0; i < line.length; i++) {          for(let j = 0; j < line[i].coords.length; j++) {              polyline.addPoint({x: line[i].coords[j][0]*300, y: -line[i].coords[j][1]*300});              if(num === '68'){//APM线(有两条,但是点是在同一个数组中的)                  if(i === 0 && j === 0) {                      polyline.setSegments([1]);                  }                  else if(i === 1 && j === 0) {                      polyline.getSegments().push(1);                  }                  else {                      polyline.getSegments().push(2);                  }              }              }      }      polyline.setLayer('0');//将线设置在下层,点设置在上层“top”      dm.add(polyline);//将管线添加进数据容器中储存,不然这个管线属于“游离”状态,是不会显示在拓扑图上的      return polyline;  }

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/htm5ctutorials/472236.html

Like (0)
Previous 2020年10月26日
Next 2020年10月26日

精彩推荐