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 相关文章推荐
js可突破windows弹退效果代码
Aug 09 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
Dec 31 Javascript
JavaScript不刷新实现浏览器的前进后退功能
Nov 05 Javascript
js实现键盘上下左右键选择文字并显示在文本框的方法
May 07 Javascript
jQuery在线选座位插件seat-charts特效代码分享
Aug 27 Javascript
深入理解JavaScript中为什么string可以拥有方法
May 24 Javascript
JS封装的自动创建表格的实现代码
Jun 15 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Dec 15 Javascript
利用jqprint插件打印页面内容的实现方法
Jan 09 Javascript
教你如何用node连接redis的示例代码
Jul 12 Javascript
Vue基于localStorage存储信息代码实例
Nov 16 Javascript
ant design vue的form表单取值方法
Jun 01 Vue.js
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 simplexmlElement操作xml的命名空间实现代码
2011/01/04 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
php时间戳转换代码详解
2019/08/04 PHP
图片上传即时显示缩略图的js代码
2009/05/27 Javascript
理解 JavaScript 预解析
2009/10/25 Javascript
JavaScript:new 一个函数和直接调用函数的区别分析
2013/07/10 Javascript
禁用Enter键表单自动提交实现代码
2014/05/22 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
BootStrap 附加导航组件
2016/07/22 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
2016/11/01 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
浅谈Vue.js
2017/03/02 Javascript
Angularjs 动态添加指令并绑定事件的方法
2017/04/13 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
微信小程序swiper实现滑动放大缩小效果
2018/11/15 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
JS控制只能输入数字并且最多允许小数点两位
2019/11/24 Javascript
python提取页面内url列表的方法
2015/05/25 Python
Python中threading模块join函数用法实例分析
2015/06/04 Python
12步教你理解Python装饰器
2016/02/25 Python
Python基于回溯法子集树模板解决旅行商问题(TSP)实例
2017/09/05 Python
详谈python3 numpy-loadtxt的编码问题
2018/04/29 Python
pyqt5移动鼠标显示坐标的方法
2019/06/21 Python
使用Python实现图像标记点的坐标输出功能
2019/08/14 Python
python如何判断IP地址合法性
2020/04/05 Python
Python selenium自动化测试模型图解
2020/04/15 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
Python OpenCV实现测量图片物体宽度
2020/05/27 Python
全球性的在线商店:Vogca
2019/05/10 全球购物
说出数据连接池的工作机制是什么?
2013/04/19 面试题
Java Servlet API中forward() 与redirect()的区别
2014/04/20 面试题
主管会计岗位职责
2014/03/13 职场文书
取保候审保证书
2014/04/30 职场文书
2015年党建工作总结
2015/03/30 职场文书
python自动计算图像数据集的RGB均值
2021/06/18 Python
Python中第三方库Faker的使用详解
2022/04/02 Python