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 图片轮换效果
Jul 29 Javascript
javascript中IE浏览器不支持NEW DATE()带参数的解决方法
Mar 01 Javascript
jquery制作 随机弹跳的小球特效
Feb 01 Javascript
js实现二级菜单渐隐显示
Nov 03 Javascript
JavaScript模拟push
Mar 06 Javascript
基于 Node.js 实现前后端分离
Apr 23 Javascript
详解jQuery中的DOM操作
Dec 23 Javascript
js实现延迟加载的几种方法
Apr 24 Javascript
提高Node.js性能的应用技巧分享
Aug 10 Javascript
JavaScript+H5实现微信摇一摇功能
May 23 Javascript
vue视图不更新情况详解
May 16 Javascript
关于微信小程序map组件z-index的层级问题分析
Jul 09 Javascript
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
hadoop常见错误以及处理方法详解
2013/06/19 PHP
Laravel 5框架学习之子视图和表单复用
2015/04/09 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
跟着JQuery API学Jquery 之二 属性
2010/04/09 Javascript
JavaScript编程开发中的五个实用小技巧
2010/07/22 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
为jquery的ajaxfileupload增加附加参数的方法
2014/03/04 Javascript
JavaScript中判断原生函数检查function是否是原生代码
2014/09/09 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
JavaScript动态插入CSS的方法
2015/12/10 Javascript
分享jQuery网页元素拖拽插件
2020/12/01 Javascript
微信小程序-拍照或选择图片并上传文件
2017/01/06 Javascript
详解Vue用自定义指令完成一个下拉菜单(select组件)
2017/10/31 Javascript
浅谈React之状态(State)
2018/09/19 Javascript
jQuery表单选择器用法详解
2019/08/22 jQuery
vue点击自增和求和的实例代码
2019/11/06 Javascript
Vue SPA 初次进入加载动画实现代码
2019/11/14 Javascript
Vue 一键清空表单的实现方法
2020/02/07 Javascript
利用Anaconda简单安装scrapy框架的方法
2018/06/13 Python
Python基于pandas实现json格式转换成dataframe的方法
2018/06/22 Python
Python数据抓取爬虫代理防封IP方法
2018/12/23 Python
python高斯分布概率密度函数的使用详解
2019/07/10 Python
Python colormap库的安装和使用详情
2020/10/06 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
CSS3 网页下拉菜单代码解释 中文翻译
2010/02/27 HTML / CSS
css3一款3D字体带阴影效果的实现步骤
2013/03/20 HTML / CSS
AVON雅芳官网:世界上最大的美容化妆品公司之一
2016/11/02 全球购物
J2EE系统只能是基于web
2015/09/08 面试题
会计专业自我鉴定范文
2013/10/06 职场文书
应届本科生推荐信范文
2013/12/25 职场文书
医学专业本科毕业生自我鉴定
2013/12/28 职场文书
平安建设实施方案
2014/03/19 职场文书
市场营销专业毕业生求职信
2014/07/21 职场文书
现场施工员岗位职责
2015/04/11 职场文书
淮海战役观后感
2015/06/11 职场文书
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP