javascript html5 canvas实现可拖动省份的中国地图


Posted in Javascript onMarch 11, 2016

本文实例分享了html5 canvas可拖动省份的中国地图实现方法,供大家参考,具体内容如下

1.数据获取
画地图需要省份边界坐标,理论上可以每次都用百度API获取数据并绘图,但为了增加效率,首先将所有坐标都获取下来并存入数据库中。
新建省份数据数组

var allZoneData = [{'name':'辽宁省','been':'yes','id':'01'},<span style="font-family: Arial, Helvetica, sans-serif;">{'name':'吉林省','been':'yes','id':'02'},……];</span> 

轮询该数组,根据省份名称请求百度API获取坐标数据,并将数据以ajax方式放松给php
var myGeo = new BMap.Geocoder(); 
 
(function(){ 
 for(var i = 0;i < allZoneData.length;i++){ 
  getAllZone(allZoneData[i].name,allZoneData[i].been,allZoneData[i].id); 
 } 
})(); 
//name为省份名,been表示是否去过,id为唯一标识,cir为省份圈号(有可能一个省份有两部分封闭圆圈构成) 
function getAllZone (name,been,id) { 
 var data,temp; 
         
 var bdary = new BMap.Boundary(); 
 bdary.get(name, function(rs){ 
  var count = rs.boundaries.length;  
  for(var j = 0; j < count; j++){      
   var ply = new BMap.Polygon(rs.boundaries[j], {strokeWeight: 2, strokeColor: "#ff0000"}); 
   data = ply.getPath(); 
   $.ajax({ 
    url: "addData.php", 
    type:"POST", 
    data: {'data':data,'name' : name,'cir':j,'been':been,'id':id}, 
    success: function(txt){ 
     console.log(txt); 
    }, 
    error: function(){ 
     alert('添加数据出错!'); 
    } 
   });   
  }         
 });         
}

php得到数据后,解析数据并将数据存储到事先建好的数据库中

<?php 
  header("content-type:text/html; charset=utf-8"); 
  $data = $_REQUEST['data']; 
  $name = $_REQUEST['name']; 
  $cir = $_REQUEST['cir']; 
  $been = $_REQUEST['been']; 
  $id = $_REQUEST['id']; 
 
  $con = mysql_connect("localhost","……","……"); 
  if (!$con){ 
    die('Could not connect: ' . mysql_error()); 
  } 
  mysql_select_db("……", $con); 
  mysql_set_charset('utf8',$con); 
 
  foreach ($data as $temp){ 
    $sql = "insert into place (id,name,lng,lat,cir,been) values ('".$id."', '".$name."', '".$temp['lng']."','".$temp['lat']."','".$cir."','".$been."')"; 
    if (!mysql_query($sql,$con)){ 
      die('Error: ' . mysql_error()); 
    } 
  } 
 
  mysql_close($con); 
  echo 'Success'; 
?>

2.画地图(base地图画在mapCanvas层)
轮询省份数组,并以ajax方式请求该省份边界坐标,然后绘图

var drawMap = function (context,data,l,t) { //context为绘制所在的层,l和t为相对位置,data为边界对象数组 
 if(data.been == 'yes'){ 
  context.fillStyle = "green"; 
 }else{ 
  context.fillStyle = "grey"; 
 } 
 context.globalAlpha = 0.8; 
 context.beginPath(); 
 cleft = (data.coordinate[0].lng - temp_left) * bigger + l; //temp_left和temp_top为地图偏移位置. 
 ctop = (temp_top - data.coordinate[0].lat) * bigger + t; //bigger为放大倍数 
 
 context.moveTo(cleft,ctop); 
           
 for(var j = 1;j < data.coordinate.length;j++){ 
  cleft = (data.coordinate[j].lng - temp_left) * bigger + l; 
  ctop = (temp_top - data.coordinate[j].lat) * bigger + t; 
  context.lineTo(cleft,ctop); 
 } 
           
 context.closePath(); 
 context.stroke(); 
 context.fill(); 
}

3.画移动连线(连线和移动的省份画在moveMapCanvas层)
当在地图上拖动省份时,出现若干条连接移动的省份和原省份的直线

var drawLinkLine = function(data,l,t){ //此处的l和t表示移动的相对位置 
 for(var k = 0;k < data.coordinate.length;k++){ 
  if(k % 60 == 0){ 
   moveMapContext.beginPath(); 
           
   //根据移动距离的不同,设置连线的粗细 
   lineLength = Math.sqrt(l * l + t * t) / 100; 
   lineLength = lineLength >= 4.5 ? 4.5 : lineLength; 
   moveMapContext.lineWidth = 5 - lineLength; 
 
   moveMapContext.strokeStyle = "rgba(0,120,60,0.4)"; 
   cleft = (data.coordinate[k].lng - temp_left) * bigger; 
   ctop = (temp_top - data.coordinate[k].lat) * bigger; 
   moveMapContext.moveTo(cleft,ctop); 
 
   cleft = (data.coordinate[k].lng - temp_left) * bigger + l; 
   ctop = (temp_top - data.coordinate[k].lat) * bigger + t; 
   moveMapContext.lineTo(cleft,ctop); 
   moveMapContext.closePath(); 
   moveMapontext.stroke(); 
  } 
 } 
}

4.事件
鼠标按下事件:当点击到地图上时,要做的事是,判断点击位置,将位置信息转化成经纬度,再通过百度API根据经纬度获得省份名称。

$('#eventCanvas').mousedown(function(ev){ 
 //获取点击canvas的坐标 
 var mouseX, mouseY; 
 if(ev.layerX || ev.layerX==0){ 
  mouseX = ev.layerX; 
  mouseY = ev.layerY; 
 }else if(ev.offsetX || ev.offsetX==0){ 
  mouseX = ev.offsetX; 
  mouseY = ev.offsetY; 
 } 
 
 //保存点击时的原坐标值 
 tempX = mouseX; 
 tempY = mouseY; 
 
 //将坐标转化为经纬度 
 mouseX = mouseX/bigger + temp_left; 
 mouseY = temp_top - mouseY/bigger; 
 
 if(opts.dragAll){ 
  draging = true; 
 }else{ 
  moveMapContext.clearRect(0, 0, 1100, 630); 
  //根据经纬度获得所在地理位置并获取边界坐标再画线 
  myGeo.getLocation(new BMap.Point(mouseX, mouseY), 
   function(result){ 
    tempName = ''; 
    draging = true; 
    name = result.addressComponents.province; 
    tempName = name; 
    pubFuns.drawMoveLayerLine(0,0);    
  }); 
 } 
});

鼠标移动事件:根据点击的省份名,获得数据,并实时重绘移动层的省份

$('#eventCanvas').mousemove(function(ev){ 
 var mouseX, mouseY; 
 if(ev.layerX || ev.layerX==0){ 
  mouseX = ev.layerX; 
  mouseY = ev.layerY; 
 }else if(ev.offsetX || ev.offsetX==0){ 
  mouseX = ev.offsetX; 
  mouseY = ev.offsetY; 
 } 
 if(draging){ 
  if(opts.dragAll){ <span style="font-family: Arial, Helvetica, sans-serif;">//拖动整个地图,存在问题,地图画的太慢</span> 
   mapContext.clearRect(0, 0, 1100, 630); 
   for(var i = 0;i < allZoneData.length;i++){ 
    for(var j = 0;j < allData[allZoneData[i].name].length;j++){ //allData是第一次读取数据时放到内存里的变量,它包含了所有数据 
     pubFuns.drawMap(mapContext,allData[allZoneData[i].name][j],mouseX - tempX, mouseY - tempY); 
    } 
   } 
   }else{ 
    moveMapContext.clearRect(0, 0, 1100, 630); 
    pubFuns.drawMoveLayerLine(mouseX - tempX, mouseY - tempY); 
   }  
  } 
});

鼠标抬起事件:设置dragging为false,clear移动层。

$('#eventCanvas').mouseup(function(e){ 
 if(opts.dragAll){  
 }else{ 
  moveMapContext.clearRect(0, 0, 1100, 630); 
 } 
 draging = false; 
});

javascript html5 canvas实现可拖动省份的中国地图

小结:功能、原理都很简单,但能熟悉canvas的一些属性和方法。canvas层是可以重叠到一起的,这样就可以在不同的层画不同的内容,方便维护和管理。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jquery中邮箱地址 URL网站地址正则验证实例代码
Sep 15 Javascript
js实现右下角提示框的方法
Feb 03 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
Nov 01 Javascript
详解vue项目优化之按需加载组件-使用webpack require.ensure
Jun 13 Javascript
[js高手之路]单例模式实现模态框的示例
Sep 01 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
Sep 06 Javascript
Angular2进阶之如何避免Dom误区
Apr 02 Javascript
node实现登录图片验证码的示例代码
Apr 20 Javascript
Express本地测试HTTPS的示例代码
Jun 06 Javascript
Echart折线图手柄触发事件示例详解
Dec 16 Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 Javascript
Jquery 获取相同NAME 或者id删除行操作
Aug 24 jQuery
js仿百度登录页实现拖动窗口效果
Mar 11 #Javascript
基于jQuery日历插件制作日历
Mar 11 #Javascript
jQuery Html控件基本操作(日常收集整理)
Mar 11 #Javascript
JavaScript获取客户端IP的方法(新方法)
Mar 11 #Javascript
JavaScript高级程序设计(第三版)学习笔记6、7章
Mar 11 #Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
Mar 11 #Javascript
Angularjs中使用Filters详解
Mar 11 #Javascript
You might like
PHP 时间日期操作实战
2011/08/26 PHP
php导出生成word的方法
2015/12/25 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
jQuery1.6 使用方法二
2011/11/23 Javascript
基于jquery的跟随屏幕滚动代码
2012/07/24 Javascript
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
百度移动版的url编码解码示例
2014/04/29 Javascript
jQuery照片伸缩效果不影响其他元素的布局
2014/05/09 Javascript
DOM基础教程之模型中的模型节点
2015/01/19 Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
2015/03/04 Javascript
Labelauty?jQuery单选框/复选框美化插件分享
2015/09/26 Javascript
js密码强度检测
2016/01/07 Javascript
vue.js树形组件之删除双击增加分支实例代码
2017/02/28 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
jQuery初级教程之网站品牌列表效果
2017/08/02 jQuery
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
2017/10/15 Javascript
详解基于Vue+Koa的pm2配置
2017/10/24 Javascript
Python中for循环控制语句用法实例
2015/06/02 Python
Python实现通过文件路径获取文件hash值的方法
2017/04/29 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
python itchat实现微信自动回复的示例代码
2017/08/14 Python
Android分包MultiDex策略详解
2017/10/30 Python
python中pip的安装与使用教程
2018/08/10 Python
pycharm 在windows上编辑代码用linux执行配置的方法
2018/10/27 Python
Python利用pandas处理Excel数据的应用详解
2019/06/18 Python
Python如何在main中调用函数内的函数方式
2020/06/01 Python
中国领先的专业家电网购平台:国美在线
2016/12/25 全球购物
毕业生个人求职信范文分享
2014/01/05 职场文书
好学生评语大全
2014/05/05 职场文书
项目战略合作意向书
2015/05/08 职场文书
婚宴新娘致辞
2015/07/28 职场文书
原生Js 实现的简单无缝滚动轮播图的示例代码
2021/05/10 Javascript
MySQL高速缓存启动方法及参数详解(query_cache_size)
2021/07/01 MySQL