摘要:公共变量最好不要在多个方法中公用,容易在增减的时候出现不必要的定时器运行到最后一天的时候要将定时器清除。程序如图附上预览地址更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界不给地址是不是对不起你们。
工作时被要求到的,结合百度地图api做一个动态展示标注变化的组件,要求地图展示某一天的标注,时间轴要求可以动态播放每一天的标注变化...然后我就开始coding...
如有不好的地方,还请大家指出,我也是小白中的一员,接下来开始正文
准备工作:
申请百度api密钥(具体方法我也不多写了,大家应该都会)
了解一下百度地图API的开发指南和类参考文档(如果嫌麻烦的话 可以直接看Demo示例)
一、首先,先加载地图,你可以用实际的经纬度定位、浏览器定位、根据ip定位、根据城市名定位,这个你可以自己选择
// 创建Map实例,设置地图允许的最小/大级别
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地图,用城市名设置地图中心点
//map.enableScrollWheelZoom(true); //启用滚轮放大缩小
centerAndZoom(center:Point, zoom:Number)
参数解释:
Point(lng:Number, lat:Number) 以指定的经度和纬度创建一个地理点坐标。
zoom:number 地图缩放级别
二、标注的使用(覆盖物)
结合百度地图api示例Demo 设置点的新图标和添加多个点示例 结合一下,就可以改写成添加多个地图标注
//编写自定义函数,创建标注
addMarker: function(point, label, status) {
// var marker = new BMap.Marker(point);
var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
anchor: new BMap.Size(16, 32), //中心点设置
infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
});
var marker = new BMap.Marker(point, {
icon: myIcon
});
TimerLine.map.addOverlay(marker);
//跳动的动画
// marker.setAnimation(BMAP_ANIMATION_BOUNCE);
marker.setAnimation(BMAP_ANIMATION_DROP);
var p = marker.getPosition();
var content = "
";
content = content + " 编号:" + label.content + " |
";
content = content + " 坐标:" + p.lng + "," + p.lat + " |
";
content = content + " 状态:" + status + " |
";
content += "
";
var infowindow = new BMap.InfoWindow(content);
//添加绑定事件
addEvent(marker, "click", getAttr);
function getAttr() {
this.openInfoWindow(infowindow);
}
}
百度地图标注添加看懂了,接下来就是动态添加标注,并且随和日期的变化而变化,比如展示垃圾箱的动态变化,8.3号清理了颜色为绿色,8.6号没清理为红色..
思想:
动态:就要使用ajax异步获取数据
变化:就要使用定时器(setInterval或者 setTimeout)
setInterval 循环调用
setTimeout 延迟调用 1次 具体区别可以自行百度
动手写插件
function addEvent(dom, type, fn) {
//对于支持DOM2级事件处理程序addeventListener方法的浏览器
if (dom.addEventListener) {
dom.addEventListener(type, fn, false);
} else if (dom.attachEvent) {
//对于不支持addEventListener方法但支持attchEvent方法的浏览器
dom.attachEvent("on" + type, fn);
} else {
//对于不支持以上两种,但支持on+"事件名"的浏览器
dom["on" + type] = fn;
}
}
var TimerLine = {
data: {
containerDiv: "timerline", //容器盒子id
datesDiv:"dates",//日期盒子id
btnsDiv:"timerlineBtns",
btns: {
play: "timerbtn-play",
stop: "timerbtn-stop",
pre:"timerbtn-pre",
next:"timerbtn-next"
},
processDiv:"processbar", //进度条div
},
protect:{
lock_play:false,
lock_stop:false,
index_label:1,
index_process:0
},
rubbish_datas: [], //用来存储ajax获取到的数据
index: 0, //变化的index
Interval_label: null,
Interval_process:null,
map: new BMap.Map("allmap", {
minZoom: 14,
maxZoom: 20
}),
Utils: {
//编写自定义函数,创建标注
addMarker: function(point, label, status) {
// var marker = new BMap.Marker(point);
var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
anchor: new BMap.Size(16, 32), //中心点设置
infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
});
var marker = new BMap.Marker(point, {
icon: myIcon
});
TimerLine.map.addOverlay(marker);
//跳动的动画
// marker.setAnimation(BMAP_ANIMATION_BOUNCE);
marker.setAnimation(BMAP_ANIMATION_DROP);
var p = marker.getPosition();
var content = "
";
content = content + " 编号:" + label.content + " |
";
content = content + " 坐标:" + p.lng + "," + p.lat + " |
";
content = content + " 状态:" + status + " |
";
content += "
";
var infowindow = new BMap.InfoWindow(content);
//添加绑定事件
addEvent(marker, "click", getAttr);
function getAttr() {
this.openInfoWindow(infowindow);
}
},
/**
* 地图标注方法
* 参数: datas:标注物数组{date:"",info:{}}
* index:序数(日期)
* */
mapSetLabel: function(datas, n,isInterval) {
TimerLine.map.clearOverlays();
var index;
console.log(TimerLine.protect.index_label);
if(isInterval){
TimerLine.protect.index_label++;
if (TimerLine.protect.index_label >= TimerLine.rubbish_datas.length - 1) {
TimerLine.protect.index_label = TimerLine.rubbish_datas.length - 1;
clearInterval(TimerLine.Interval_label);
TimerLine.protect.lock_play=false;
}
}
if (n == null) {
if(TimerLine.protect.index_label==0){
TimerLine.protect.index_label=1
}
index = TimerLine.protect.index_label;
} else {
index = parseInt(n);
TimerLine.protect.index_label = index;
}
var info = datas[index].info;
var info_count=0;
var addMarker_Interval=setInterval(function(){
var p = info[info_count].point.split(",");
var p_x = parseFloat(p[0].toString()); //纬度
var p_y = parseFloat(p[1].toString()); //经度
//创建label标签
var label = new BMap.Label(info[info_count].title, {
offset: new BMap.Size(20, -10)
});
//创建标注点
var point = new BMap.Point(p_x, p_y);
//状态(垃圾箱状态)
var status = info[info_count].status;
//添加标注的方法
TimerLine.Utils.addMarker(point, label, status);
info_count++;
if(info_count>=info.length){
clearInterval(addMarker_Interval);
}
},0);
},
//添加日期点击事件绑定 dates li click
bindEvent: function() {
var datesDiv = document.getElementById("dates");
addEvent(datesDiv,"click",function(e){
var event = e || window.e;
var target = event.target || event.srcElement;
for(var i=0;i
= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_process = TimerLine.rubbish_datas.length-1;
clearInterval(TimerLine.Interval_process);
TimerLine.protect.lock_play=false;
}
}
var datesDiv = document.getElementById("dates");
var processDiv = document.getElementById(TimerLine.data.processDiv);
if(index==null){
processDiv.style.width =parseInt(processDiv.style.width)+datesDiv.getElementsByTagName("li")[0].offsetWidth+"px";
}else{
processDiv.style.width =datesDiv.getElementsByTagName("li")[0].offsetWidth*parseInt(index+1)+"px";
}
}
},
//TimerLine初始化
init: function() {
this.createMap();
this.ajaxCreate();
//事件绑定
this.bindEvent();
},
createMap: function() {
// 创建Map实例,设置地图允许的最小/大级别
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地图,用城市名设置地图中心点
//map.enableScrollWheelZoom(true); //启用滚轮放大缩小
},
ajaxCreate: function() {
var That = this;
var containerDiv = That.data.containerDiv;
$.ajax({
type: "get",
url: "js/json.json",
dataType: "json",
success: function(data) {
containerDiv = document.getElementById(containerDiv); //容器id
That.rubbish_datas = data.result.datas; //
//console.log(That.rubbish_datas);
That.create(containerDiv, That.rubbish_datas);
//日期时间绑定
That.Utils.bindEvent();
}
});
},
create: function(containerDiv, datas) {
var That = this;
var datasDiv ="";
// var datasDiv = "";
datasDiv += "";
for (var i = 0; i < datas.length; i++) {
datasDiv += "- " + datas[i].date + "
";
}
datasDiv += "
";
document.getElementById(That.data.btnsDiv).innerHTML=""
//创建第一天的标注
this.Utils.mapSetLabel(datas, 0,false);
// console.log(TimerLine.index);
That.datas = datas;
containerDiv.innerHTML = datasDiv;
},
//播放 暂停 委托事件----时间绑定
bindEvent: function() {
if (this.data.btns == null)
return;
var That = this;
addEvent(document.getElementById(That.data.btnsDiv), "click", function(e) {
var event = e || window.e;
var target = event.target || event.srcElement;
//播放事件
if (target.id == That.data.btns.play) {
if(!TimerLine.protect.lock_play){
if(TimerLine.protect.index_label >= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_label=0;
var processDiv = document.getElementById(TimerLine.data.processDiv);
var datesDiv = document.getElementById("dates");
processDiv.style.width = datesDiv.getElementsByTagName("li")[0].offsetWidth+"px";
}
if(TimerLine.protect.index_process >= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_process=0;
}
//
TimerLine.Interval_label = setInterval("TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas,null,true)", 1000);
TimerLine.Interval_process = setInterval("TimerLine.Utils.Setprocess(null,true)",1000);
$("#timerbtn-play").attr("class","iconfont icon-zanting1");
//播放枷锁
TimerLine.protect.lock_play=true;
//暂停解锁
TimerLine.protect.lock_stop=false;
}else if(TimerLine.protect.lock_play){
$("#timerbtn-play").attr("class","iconfont icon-zanting");
TimerLine.Interval_label&&clearInterval(TimerLine.Interval_label);
TimerLine.Interval_process&&clearInterval(TimerLine.Interval_process);
//播放解锁
TimerLine.protect.lock_play=false;
//暂停加锁
TimerLine.protect.lock_stop=true;
}
}
if(target.id == That.data.btns.pre){
if(TimerLine.protect.index_label==0) return;
TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label-1,false);
TimerLine.Utils.Setprocess(TimerLine.protect.index_process-1,false);
TimerLine.protect.index_process=TimerLine.protect.index_process-1;
}
if(target.id == That.data.btns.next){
if(TimerLine.protect.index_label==TimerLine.rubbish_datas.length-1) return;
TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label+1,false);
TimerLine.Utils.Setprocess(TimerLine.protect.index_process+1,false);
TimerLine.protect.index_process=TimerLine.protect.index_process+1;
}
});
}
}
TimerLine.init();
以上是我自己手写的组件代码,对设计模式了解还是一般.本来是想用原型模式写,不过在setInterval时候,方法没法调用原型方法,让后我就改成了单例模式
TimeLine组件介绍
data:数据容器绑定
protect 保护属性 (对播放、暂停、时间轴index、标注index)
rubbish_datas 存储ajax读取的数据
Interval_label 百度地图标注定时器
Interval_process 时间轴定时器
Utils 工具类
init() TimeLine初始化
createMap() 创建百度地图
ajaxCreate() 获取数据,创建容器(create()),时间绑定(bindEvent())
遇到的问题:
两个定时器运行时,公共index 容易读取错误,一个定时器修改了index 另一个定时器还没修改,这样造成了创建标注与当前时间不符合,
注:要将修改公共变量尽量写在一个方法中。公共变量最好不要在多个方法中公用,容易在增减的时候出现不必要的BUG
定时器运行到最后一天的时候要将定时器清除。
程序如图:
附上预览地址
更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界!
不给 Demo 地址 是不是对不起你们。哈哈?
可以关注微信公众号 回复百度地图时间轴组件 ,即可收到 Demo 的地址。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86903.html