我正在參加「掘金·啟航計劃」
1.微信公眾平台註冊一個小程序賬號,註冊完之後左邊菜單列表點擊開發管理->開發設置,就可以看到自己的appid(小程序id)了
2.官網安裝微信開發者工具
打開微信開發者工具選擇創建小程序,輸入項目名稱,目錄自定義,將appid複製進AppID裏,點擊創建
appid
這是新創建好的小程序目錄,裏面非常多文件是不需要的,我們要刪除多餘的文件
這是刪除好的文件目錄,可以看到簡潔很多了
pages文件夾是存放頁面的文件夾,右擊新建index文件夾,再右擊新建Page自動創建js,json,wxml,wxss文件
.js
.json
頁面的 .json
app.json
.wxml
.wxss
json文件裏添加navigationBarTitleText設置導航欄標題
導入一張紅色圓點的圖片用作跑步時的定位標記
創建四個按鈕分別用作開始記錄/暫停記錄,清除數據,保存數據,回放,並創建對應的方法
<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="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>
<view class="counter"> <text>里程:{{mdl.formatKM(meters)}} 時間: {{mdl.formatTime(seconds)}}</text> </view> 使用小程序官方內置的map地圖組件,裏面有好幾十個屬性,但我們具體只使用一下幾個屬性: - latitude:number類型,中心緯度 - longitude:number類型,中心經度 - markers:array類型,標記點 - polyline:array類型,路線
<view class="counter"> <text>里程:{{mdl.formatKM(meters)}} 時間: {{mdl.formatTime(seconds)}}</text> </view>
latitude
longitude
markers
polyline
```
.header{ display: flex; } .counter{ text-align: center; } .map{ width: 100%; height: 90vh; }
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地圖上下文
Page({ data:{ meters:0,//里程 seconds:0,//時間 latitude:0,//緯度 longitude:0,//經度 running:false,//是否開始 interval:1000,//多少秒獲取當前定位 markers:[],//標記 polyline:[],//路線 point:[],//標註 i:0, ii:0 } })
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 }) }) }, 這樣地圖就可以顯示出來了
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 dMath.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=2RMath.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 }) }) }, 然後出門走一圈記錄記錄😤😤😤
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 }) }, 點擊保存數據按鈕時將數據添加進本地緩存中
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() }, 點擊回放按鈕,開始回放記錄
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) } }) }
回放效果,動畫比較簡陋啊😛😛,可以自己設置樣式: