This article mainly introduces the relevant information on the Chinese map of draggable provinces in javascript html5 canvas. Friends in need can refer to it
The example of this article shares the implementation of the Chinese map of draggable provinces in html5 canvas. Method, for your reference, the specific content is as follows
1. Data acquisition
Drawing a map requires province boundary coordinates. In theory, you can use Baidu API to obtain data and draw every time, but In order to increase efficiency, all coordinates are first obtained and stored in the database.
Create a new province data array
Copy code The code is as follows:
var allZoneData = [{'name':'Liaoning province','been':'yes','id':'01'},{'name':'Jilin Province' ,'been':'yes','id':'02'},……];
Poll the array and request Baidu API to obtain coordinate data based on the province name , and relax the data to php in ajax mode
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('添加数据出错!'); } }); } }); }
2. Draw a map (the base map is drawn on the mapCanvas layer)
Poll the province array and use Ajax method requests the boundary coordinates of the province, and then draws
<?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'; ?>
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(); }
4. Event
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(); } } }
Mouse movement event: obtain data based on the clicked province name, and redraw the province of the mobile layer in real time
$('#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); } } });