准备工作
1.微信公众平台注册一个小程序账号,注册完之后左边菜单列表点击开发管理->开发设置,就可以看到自己的appid(小程序id)了
2.官网安装微信开发者工具
创建项目
1.创建小程序项目
打开微信开发者工具选择创建小程序,输入项目名称,目录自定义,将appid
复制进AppID里,点击创建
2.初始化小程序项目
这是新创建好的小程序目录,里面非常多文件是不需要的,我们要删除多余的文件
这是删除好的文件目录,可以看到简洁很多了
pages文件夹是存放页面的文件夹,右击新建index文件夹,再右击新建Page自动创建js,json,wxml,wxss文件
.js
里面编写一些生命周期钩子,事件处理,全局数据….json
里面编写一些页面配置,页面的 .json
配置会覆盖app.json
的配置.wxml
里面编写一些页面内容,UI标签,数据绑定.wxss
里面编写一些样式
json文件里添加navigationBarTitleText设置导航栏标题
导入一张红色圆点的图片用作跑步时的定位标记
开始编写
1.wxml
创建四个按钮分别用作开始记录/暂停记录,清除数据,保存数据,回放,并创建对应的方法
<view class="header">
<button type="primary" size="mini" bindtap="run">{{running?'暂停记录':'开始记录'}}</button>
<button type="warn" size="mini" bindtap="clear">清除数据</button>
<button type="default" size="mini" bindtap="save">保存数据</button>
<button type="primary" size="mini" bindtap="translateMarker">回放</button>
</view>
创建text标签用作记录里程和时间
<view class="counter">
<text>里程:{{mdl.formatKM(meters)}} 时间: {{mdl.formatTime(seconds)}}</text>
</view>
使用小程序官方内置的map地图组件,里面有好几十个属性,但我们具体只使用一下几个属性:
latitude
:number类型,中心纬度longitude
:number类型,中心经度markers
:array类型,标记点polyline
:array类型,路线
<map id="map" class="map" latitude="{{latitude}}" longitude="{{longitude}}" markers="{{markers}}" polyline="{{polyline}}" />
2.wxss
.header{
display: flex;
}
.counter{
text-align: center;
}
.map{
width: 100%;
height: 90vh;
}
3.js
js文件为我们创建好了一些生命周期函数,但是看起来太乱了
直接ctrl+a全选删除,再把page添加回去,dada里初始一些数据
Page({
data:{
meters:0,//里程
seconds:0,//时间
latitude:0,//纬度
longitude:0,//经度
running:false,//是否开始
interval:1000,//多少秒获取当前定位
markers:[],//标记
polyline:[],//路线
point:[],//标注
i:0,
ii:0
}
})
进入小程序在onLoad生命周期里获取当前位置,onReady里设置map地图上下文
onReady:function () {
//MapContext 实例,可通过wx.createMapContext获取,通过 `id` 跟一个map组件绑定,操作对应的map组件
this.mapCtx = wx.createMapContext('map')
},
onLoad(){
this.curLocation()
},
curLocation(){
//wx.getLocation获取当前的地理位置,type设置'gcj02'返回gps坐标
wx.getLocation({
type: 'gcj02',
}).then(res=>{
console.log(res)
let{latitude,longitude}=res
this.setData({
latitude,longitude
})
})
},
这样地图就可以显示出来了
在点击开始记录按钮来记录数据前新建一个utils.js文件用于计算距离并向外导出,在index.js里引入
//index.js
const utils=require('utils')
//utils.js
//弧度
function toRadians(d){
return d*Math.PI/180
}
//利用两点的经度,维度计算两点距离
function getDistance(lat1,lng1,lat2,lng2){
const R=6378137 //赤道半径
let dis=0
let deltaLat=toRadians(lat1)-toRadians(lat2)
let deltaLng=toRadians(lng1)-toRadians(lng2)
dis=2*R*Math.asin(Math.sqrt(Math.pow(Math.sin(deltaLat/2),2)
+Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(deltaLng/2),2)))
return dis
}
module.exports={
getDistance
}
然后可以点击开始按钮进行记录数据了,在onLoad里添加一个定时器用于记录数据
onLoad(){
this.curLocation()
setInterval(this.record,this.data.interval)
},
run(){
this.setData({
running:!this.data.running
})
},
record(){
//没有开始记录return出去
if(!this.data.running){
return
}
this.setData({
seconds:this.data.seconds+this.data.interval/1000
})
wx.getLocation({
type: 'gcj02',
}).then(res=>{
//当前标记位置信息
let newMarker={
latitude:res.latitude,
longitude:res.longitude,
iconPath:'hd.png',
width:12,
height:12,
id:1+this.data.i
}
let i=this.data.i
let point=this.data.point
let pace=0
let markers=this.data.markers
if(this.data.markers.length>0){
let lastmarker=this.data.markers.slice(-1)[0]
//根据上一次标记点和当前标记点计算距离,超出15m添加标记,否则视为距离太短不添加标记
pace=utils.getDistance(lastmarker.latitude,lastmarker.longitude,
newMarker.latitude,newMarker.longitude)
if(pace>15){
markers.push(newMarker)
i=this.data.i+1
point.push({longitude:res.longitude,latitude:res.latitude})
}else{
pace=10
}
}else{
markers.push(newMarker)
i=this.data.i+1
point.push({longitude:res.longitude,latitude:res.latitude})
}
this.setData({
latitude:res.latitude,
longitude:res.longitude,
markers,
point,
meters:this.data.meters+pace,
i
})
})
},
然后下一个按钮清除数据
clear(){
this.setData({
markers:[],
meters:0,
seconds:0,
polyline:[],
point:[],
i:0,
ii:0
})
},
点击保存数据按钮时将数据添加进本地缓存中
save(){
//没有暂停记录return出去
if(this.data.running){
return
}
let point=this.data.point
let markers=this.data.markers
//point添加数组第一个数组,回放线路时形成一个闭环
point.push(point[0])
markers.push(markers[0])
this.setData({
polyline:[{
points:point,
color:'#99ff00',
width:10,
dottedLine:false
}]
})
wx.setStorage({
data:{
markers:this.data.markers,
seconds:this.data.seconds,
polyline:this.data.polyline,
point:this.data.point,
meters:this.data.meters
},
key:'running',
}).then(()=>{
wx.showToast({
title: '保存成功',
})
})
//本地缓存后清理数据
this.clear()
},
点击回放按钮,开始回放记录
translateMarker() {
let that=this
//获取本地缓存
wx.getStorage({
key:'running',
success:function (res) {
console.log(res.data.markers)
let running=res.data
that.setData({
markers:running.markers,
point:running.point,
polyline:running.polyline,
seconds:running.seconds,
meters:running.meters
})
}
})
let ii=this.data.ii
let markers=this.data.markers
let markerId = markers[ii].id;
let destination = {
longitude: markers[ii+1].longitude,
latitude: markers[ii+1].latitude
};
//使每个不同距离的标记点匀速平移滑动,duration固定的话标记点距离不同动画会时快时慢
let duration=utils.getDistance(markers[this.data.ii].latitude,markers[this.data.ii].longitude,markers[this.data.ii+1].latitude,markers[this.data.ii+1].longitude)*5
//回放使用MapContext.translateMarker
this.mapCtx.translateMarker({
markerId: markerId,//当前标记点
destination: destination,//要移动到的下一个标记点
autoRotate: false,//关闭旋转
duration: duration,//动画市场
success(res) {
that.setData({
ii: that.data.ii + 1
});
// 小于长度减1继续下一个标记点动画
if (that.data.ii < markers.length-1) {
that.translateMarker();
}
},
fail(err) {
console.log('fail', err)
}
})
}
回放效果,动画比较简陋啊😛😛,可以自己设置样式: