准备工作
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
})
})
},
复制代码
然后出门走一圈记录记录😤😤😤
ok 没问题,然后下一个按钮清除数据
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)
}
})
}
复制代码
回放效果,动画比较简陋啊😛😛,可以自己设置样式:
评论