uniapp封裝地圖運(yùn)動(dòng)軌跡完整實(shí)例代碼
注意:封裝的地圖運(yùn)動(dòng)軌跡只測(cè)試了微信小程序,其他平臺(tái)未測(cè)試
不過實(shí)現(xiàn)功能的核心API就是這幾個(gè):uniapp.dcloud.net.cn/api/locatio…
展示的核心組件是:uniapp.dcloud.net.cn/component/m…
不同平臺(tái)根據(jù)文檔中的差異說明修改代碼即可
實(shí)現(xiàn)的功能:
- 獲取當(dāng)前位置信息并展示
- 在前/后臺(tái)實(shí)時(shí)獲取運(yùn)動(dòng)軌跡并渲染
- 支持暫停/繼續(xù)記錄軌跡
功能效果:

軌跡效果如下圖(由于開發(fā)的時(shí)候不方便肉身移動(dòng),所以就貼一張靜態(tài)的軌跡圖吧)

開始前先在配置文件manifest.json中找到 mp-weixin 的配置項(xiàng),然后加上下面的配置
"permission": {
"scope.userLocation": {
"desc": "你的位置信息將用于小程序位置接口的效果展示"
}
},
"requiredPrivateInfos": [
"getLocation",
"startLocationUpdate",
"startLocationUpdateBackground",
"onLocationChange"
],
"requiredBackgroundModes": ["location"],代碼
<template>
<view class="container">
<!-- 地圖容器 -->
<map
id="map"
class="map"
:latitude="mapCenter.latitude"
:longitude="mapCenter.longitude"
:scale="16"
:markers="markers"
:polyline="polyline"
:enable-3D="true"
:show-compass="false"
:enable-zoom="true"
:enable-scroll="true"
:enable-rotate="true"
:enable-overlooking="true"
:enable-satellite="false"
:enable-traffic="false"
:show-location="true"
></map>
<div class="operate-box" v-if="!isViewMode">
<!-- 定位模式切換 -->
<view class="mode-panel" v-if="!isTracking">
<view class="mode-item">
<text class="mode-label">定位模式 :</text>
<view class="mode-switch">
<text class="mode-text" :class="{ active: !isBackgroundMode }">前臺(tái)定位</text>
<switch
:checked="isBackgroundMode"
:disabled="!isLocationBackgroundAuth"
@change="toggleBackgroundMode"
color="#007AFF"
/>
<text class="mode-text" :class="{ active: isBackgroundMode }">后臺(tái)定位</text>
</view>
</view>
</view>
<!-- 控制按鈕 -->
<view class="control-panel">
<view class="control-btn" :class="{ active: isTracking }" @click="toggleTracking">
{{ isTracking ? '結(jié)束記錄' : '開始記錄' }}
</view>
<view
class="control-btn pause-btn"
:class="{ 'pause-active': isPause }"
v-if="isTracking"
@click="togglePause"
>
{{ isPause ? '繼續(xù)記錄' : '暫停記錄' }}
</view>
<view class="control-btn" v-if="!isTracking && trackPoints.length > 0" @click="saveTrack">
保存軌跡記錄
</view>
</view>
</div>
<!-- 運(yùn)動(dòng)信息面板 -->
<view class="info-panel" v-if="trackPoints.length > 0 || isViewMode">
<!-- 暫停狀態(tài)提示 -->
<view class="pause-status" v-if="isPause">
<text class="pause-text">?? 記錄已暫停</text>
</view>
<view class="info-item">
<text class="info-label">總距離:</text>
<text class="info-value">{{ !isViewMode ? totalDistance : viewModeTotalDistance }}km</text>
</view>
<view class="info-item">
<text class="info-label">運(yùn)動(dòng)時(shí)長(zhǎng):</text>
<text class="info-value">{{ !isViewMode ? formatDuration : viewModeFormatDuration }}</text>
</view>
<view class="info-item">
<text class="info-label">平均速度:</text>
<text class="info-value">{{ !isViewMode ? averageSpeed : viewModeAverageSpeed }}km/h</text>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
computed,
watchEffect,
getCurrentInstance,
onBeforeUnmount,
nextTick,
} from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const { proxy } = getCurrentInstance();
const eventChannel = proxy.getOpenerEventChannel();
import { getSetting } from '@/utils/index';
onLoad((res) => {
if (res.viewId) {
viewId = res.viewId;
isViewMode.value = true;
let trackData = uni.getStorageSync('trackData') || [];
trackData = trackData.find((item) => item.id == viewId);
if (trackData) {
mapCenter.value = trackData.mapCenter;
markers.value = trackData.markers;
polyline.value = trackData.polyline;
viewModeTotalDistance.value = trackData.viewModeTotalDistance;
viewModeFormatDuration.value = trackData.viewModeFormatDuration;
viewModeAverageSpeed.value = trackData.viewModeAverageSpeed;
} else {
uni.showToast({
title: '軌跡記錄不存在',
icon: 'none',
});
}
return;
}
// 檢查后臺(tái)定位權(quán)限
getSetting('scope.userLocationBackground', '請(qǐng)?jiān)谠O(shè)置中開啟后臺(tái)定位權(quán)限', () => {
isLocationBackgroundAuth.value = true;
isBackgroundMode.value = true;
});
// 檢查前臺(tái)定位權(quán)限
getSetting('scope.userLocation', '請(qǐng)?jiān)谠O(shè)置中開啟地理位置權(quán)限', () => {
isLocationAuth.value = true;
getCurrentLocation();
});
});
onBeforeUnmount(() => {
// 停止位置監(jiān)聽
stopLocationTracking();
});
const isViewMode = ref(false); // 是否是查看模式
let viewId = ''; // 查看模式下的id
const viewModeTotalDistance = ref(0); // 查看模式下的總距離
const viewModeFormatDuration = ref('00:00:00'); // 查看模式下的運(yùn)動(dòng)時(shí)長(zhǎng)
const viewModeAverageSpeed = ref('0.00'); // 查看模式下的平均速度
const isLocationAuth = ref(false); // 是否授權(quán)地理位置權(quán)限
const isLocationBackgroundAuth = ref(false); // 是否授權(quán)后臺(tái)定位權(quán)限
const isTracking = ref(false); // 是否正在記錄
const isBackgroundMode = ref(false); // 是否使用后臺(tái)定位模式
const isPause = ref(false); // 是否暫停記錄
const isContinueAfterPause = ref(false); // 是否暫停后繼續(xù)記錄
const pauseNum = ref(0); // 暫停次數(shù)
const pauseDistance = ref(0); // 暫停距離
const pauseMarker = ref({}); // 暫停點(diǎn)標(biāo)記
const trackPoints = ref([]); // 軌跡點(diǎn)
const markers = ref([]); // 地圖標(biāo)記點(diǎn)
const polyline = ref([]); // 軌跡線
// 地圖中心點(diǎn)
const mapCenter = ref({
latitude: 39.909,
longitude: 116.397,
});
let timer = null; // 定時(shí)器
const startTime = ref(null); // 開始時(shí)間
const currentTime = ref(Date.now()); // 當(dāng)前時(shí)間,用于實(shí)時(shí)更新
const pauseStartTime = ref(null); // 暫停開始時(shí)間
const totalPauseTime = ref(0); // 總暫停時(shí)間(毫秒)
// 計(jì)算兩點(diǎn)間距離(米)
function calculateDistance(lat1, lng1, lat2, lng2) {
const R = 6371000; // 地球半徑(米)
const dLat = ((lat2 - lat1) * Math.PI) / 180;
const dLng = ((lng2 - lng1) * Math.PI) / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLng / 2) *
Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
// 總距離
const totalDistance = computed(() => {
if (trackPoints.value.length < 2) return 0;
let distance = 0;
for (let i = 1; i < trackPoints.value.length; i++) {
distance += calculateDistance(
trackPoints.value[i - 1].latitude,
trackPoints.value[i - 1].longitude,
trackPoints.value[i].latitude,
trackPoints.value[i].longitude
);
}
distance -= pauseDistance.value;
return (distance / 1000).toFixed(2);
});
// 運(yùn)動(dòng)時(shí)長(zhǎng)
const formatDuration = computed(() => {
// 確保所有必要的值都存在且有效
if (!startTime.value || !currentTime.value) return '00:00:00';
// 計(jì)算實(shí)際運(yùn)動(dòng)時(shí)長(zhǎng)(排除暫停時(shí)間)
const actualDuration = currentTime.value - startTime.value - totalPauseTime.value;
// 防止出現(xiàn)負(fù)數(shù)或異常值
if (actualDuration < 0) {
console.log('運(yùn)動(dòng)時(shí)長(zhǎng)計(jì)算異常:', {
currentTime: currentTime.value,
startTime: startTime.value,
totalPauseTime: totalPauseTime.value,
actualDuration: actualDuration,
});
return '00:00:00';
}
const hours = Math.floor(actualDuration / 3600000);
const minutes = Math.floor((actualDuration % 3600000) / 60000);
const seconds = Math.floor((actualDuration % 60000) / 1000);
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds
.toString()
.padStart(2, '0')}`;
});
// 平均速度
const averageSpeed = computed(() => {
if (totalDistance.value <= 0 || !startTime.value) return 0;
// 使用實(shí)際運(yùn)動(dòng)時(shí)長(zhǎng)計(jì)算平均速度(排除暫停時(shí)間)
const actualDuration = (currentTime.value - startTime.value - totalPauseTime.value) / 3600000; // 小時(shí)
// 防止出現(xiàn)負(fù)數(shù)或異常值
if (actualDuration <= 0) return 0;
return (totalDistance.value / actualDuration).toFixed(2);
});
// 獲取當(dāng)前位置
function getCurrentLocation() {
return new Promise((resolve, reject) => {
uni.getLocation({
type: 'gcj02',
success: (res) => {
mapCenter.value = {
latitude: res.latitude,
longitude: res.longitude,
};
resolve();
},
fail: (err) => {
console.error('獲取位置失敗:', err);
reject(err);
},
});
});
}
// 添加地圖標(biāo)記點(diǎn)
function addMarker(data) {
markers.value.push({
id: data.id,
latitude: data.latitude,
longitude: data.longitude,
width: 20,
height: 20,
callout: {
content: data.content,
color: '#ffffff',
fontSize: 12,
borderRadius: 4,
bgColor: '#007AFF',
padding: 4,
display: 'ALWAYS',
},
});
console.log('添加標(biāo)記點(diǎn):', data.content, '當(dāng)前標(biāo)記點(diǎn)總數(shù):', markers.value.length);
}
// 啟動(dòng)定時(shí)器
function startTimer() {
if (timer) return;
timer = setInterval(() => {
currentTime.value = Date.now();
}, 1000); // 每秒更新一次
}
// 停止定時(shí)器
function stopTimer() {
if (timer) {
clearInterval(timer);
timer = null;
}
}
// 暫停/繼續(xù)記錄
function togglePause() {
if (isPause.value) {
// 繼續(xù)記錄
resumeTracking();
} else {
// 暫停記錄
pauseTracking();
}
}
// 暫停記錄
async function pauseTracking() {
console.log('調(diào)用暫停記錄函數(shù),當(dāng)前狀態(tài):', {
isTracking: isTracking.value,
isPause: isPause.value,
});
isPause.value = true;
pauseStartTime.value = Date.now();
// 停止位置監(jiān)聽(但不添加結(jié)束點(diǎn)標(biāo)記)
uni.stopLocationUpdate({
success: () => {
console.log('暫停位置監(jiān)聽成功');
// 移除位置變化監(jiān)聽
uni.offLocationChange();
},
fail: (err) => {
console.error('暫停位置監(jiān)聽失敗:', err);
},
});
// 停止定時(shí)器
stopTimer();
uni.showToast({
title: '已暫停記錄',
icon: 'none',
});
isContinueAfterPause.value = true;
pauseNum.value++;
await getCurrentLocation();
addMarker({
latitude: mapCenter.value.latitude,
longitude: mapCenter.value.longitude,
id: new Date().getTime(),
content: `暫停點(diǎn)${pauseNum.value}`,
});
pauseMarker.value = {
latitude: mapCenter.value.latitude,
longitude: mapCenter.value.longitude,
};
}
// 繼續(xù)記錄
async function resumeTracking() {
console.log('調(diào)用繼續(xù)記錄函數(shù),當(dāng)前狀態(tài):', {
isTracking: isTracking.value,
isPause: isPause.value,
});
isPause.value = false;
// 計(jì)算暫停時(shí)間并累加到總暫停時(shí)間
if (pauseStartTime.value) {
const pauseDuration = Date.now() - pauseStartTime.value;
totalPauseTime.value += pauseDuration;
pauseStartTime.value = null;
console.log('暫停時(shí)長(zhǎng):', pauseDuration, 'ms, 總暫停時(shí)間:', totalPauseTime.value, 'ms');
}
// 立即更新當(dāng)前時(shí)間,避免顯示暫停前的時(shí)間
currentTime.value = Date.now();
// 重新開始位置監(jiān)聽(不重新初始化,只恢復(fù)監(jiān)聽)
resumeLocationTracking();
// 重新開始定時(shí)器
startTimer();
uni.showToast({
title: '已繼續(xù)記錄',
icon: 'none',
});
await getCurrentLocation();
addMarker({
latitude: mapCenter.value.latitude,
longitude: mapCenter.value.longitude,
id: new Date().getTime(),
content: `繼續(xù)點(diǎn)${pauseNum.value}`,
});
}
// 恢復(fù)位置監(jiān)聽(不重新初始化)
function resumeLocationTracking() {
// 根據(jù)模式選擇不同的位置監(jiān)聽方式
const locationConfig = {
success: () => {
console.log('恢復(fù)位置監(jiān)聽');
// 添加位置變化監(jiān)聽
uni.onLocationChange((res) => {
handleLocationChange(res);
});
},
fail: (err) => {
console.error('恢復(fù)位置監(jiān)聽失敗:', err);
uni.showToast({
title: '恢復(fù)監(jiān)聽失敗',
icon: 'none',
});
},
};
if (isBackgroundMode.value) {
// 使用后臺(tái)定位
console.log('恢復(fù)后臺(tái)定位模式');
uni.startLocationUpdateBackground(locationConfig);
} else {
// 使用前臺(tái)定位
console.log('恢復(fù)前臺(tái)定位模式');
uni.startLocationUpdate(locationConfig);
}
}
// 開始/停止記錄
function toggleTracking() {
console.log('調(diào)用切換記錄函數(shù),當(dāng)前狀態(tài):', {
isTracking: isTracking.value,
isPause: isPause.value,
});
if (isTracking.value) {
stopLocationTracking();
} else {
startLocationTracking();
}
}
// 切換后臺(tái)定位模式
function toggleBackgroundMode(e) {
isBackgroundMode.value = e.detail.value;
console.log('切換定位模式:', isBackgroundMode.value ? '后臺(tái)定位' : '前臺(tái)定位');
}
// 開始位置監(jiān)聽
function startLocationTracking() {
console.log('調(diào)用開始位置監(jiān)聽函數(shù),當(dāng)前狀態(tài):', {
isTracking: isTracking.value,
isPause: isPause.value,
trackPointsCount: trackPoints.value.length,
});
// 防止重復(fù)調(diào)用
if (isTracking.value) {
console.log('已經(jīng)在記錄狀態(tài),跳過重復(fù)調(diào)用');
return;
}
// 如果是重新開始記錄(之前已經(jīng)停止過),重置所有時(shí)間相關(guān)狀態(tài)
// 判斷條件:有軌跡點(diǎn)且當(dāng)前不在記錄狀態(tài)且不是暫停狀態(tài),說明是重新開始
if (trackPoints.value.length > 0 && !isTracking.value && !isPause.value) {
// 重置所有狀態(tài)
resetState();
// 延遲一幀確保狀態(tài)更新后再開始監(jiān)聽
nextTick(() => {
initLocationTrackingInternal();
});
return;
}
// 正常開始記錄
initLocationTrackingInternal();
}
// 內(nèi)部初始化位置監(jiān)聽函數(shù)
async function initLocationTrackingInternal() {
if (isBackgroundMode.value) {
// 后臺(tái)定位模式
if (isLocationAuth.value && isLocationBackgroundAuth.value) {
initLocationTracking();
} else {
if (!isLocationAuth.value) {
uni.showModal({
title: '需要地理位置權(quán)限',
content: '請(qǐng)?jiān)谠O(shè)置中開啟地理位置權(quán)限',
showCancel: false,
});
} else if (!isLocationBackgroundAuth.value) {
uni.showModal({
title: '需要后臺(tái)定位權(quán)限',
content: '請(qǐng)?jiān)谠O(shè)置中開啟后臺(tái)定位權(quán)限',
showCancel: false,
});
}
}
} else {
// 前臺(tái)定位模式
if (isLocationAuth.value) {
initLocationTracking();
} else {
uni.showModal({
title: '需要地理位置權(quán)限',
content: '請(qǐng)?jiān)谠O(shè)置中開啟地理位置權(quán)限',
showCancel: false,
});
}
}
}
// 初始化位置監(jiān)聽
async function initLocationTracking() {
// 根據(jù)模式選擇不同的位置監(jiān)聽方式
const locationConfig = {
success: async () => {
console.log('開始監(jiān)聽位置變化');
isTracking.value = true;
// 只在第一次開始記錄時(shí)設(shè)置開始時(shí)間
if (!startTime.value) {
startTime.value = Date.now();
console.log('設(shè)置開始時(shí)間:', new Date(startTime.value).toLocaleString());
}
startTimer(); // 開始定時(shí)器
// 添加位置變化監(jiān)聽
uni.onLocationChange((res) => {
handleLocationChange(res);
});
// 每次開始記錄時(shí)都添加起始點(diǎn)標(biāo)記
await getCurrentLocation();
addMarker({
latitude: mapCenter.value.latitude,
longitude: mapCenter.value.longitude,
id: new Date().getTime(),
content: '起始點(diǎn)',
});
uni.showToast({
title: '已開始記錄',
icon: 'none',
});
},
fail: (err) => {
console.error('開始監(jiān)聽位置變化失敗:', err);
uni.showToast({
title: '開始監(jiān)聽失敗',
icon: 'none',
});
},
};
if (isBackgroundMode.value) {
// 使用后臺(tái)定位
console.log('使用后臺(tái)定位模式');
uni.startLocationUpdateBackground(locationConfig);
} else {
// 使用前臺(tái)定位
console.log('使用前臺(tái)定位模式');
uni.startLocationUpdate(locationConfig);
}
}
// 處理位置變化
function handleLocationChange(location) {
console.log('位置變化', location);
// 添加軌跡點(diǎn)
const point = {
latitude: location.latitude,
longitude: location.longitude,
timestamp: Date.now(),
};
if (checkLocation(point)) {
trackPoints.value.push(point);
// 更新軌跡線
updatePolyline();
}
// 更新地圖中心點(diǎn)(跟隨用戶位置)
mapCenter.value = {
latitude: location.latitude,
longitude: location.longitude,
};
}
// 校驗(yàn)返回的經(jīng)緯度是否合法:和上一個(gè)經(jīng)緯度相差不能超過100米
function checkLocation(location) {
if (trackPoints.value.length === 0) return true;
const lastPoint = trackPoints.value[trackPoints.value.length - 1];
const distance = calculateDistance(
lastPoint.latitude,
lastPoint.longitude,
location.latitude,
location.longitude
);
console.log('距離上次位置', distance + '米');
let result = distance < 100;
if (isContinueAfterPause.value) {
isContinueAfterPause.value = false;
pauseDistance.value += calculateDistance(
pauseMarker.value.latitude,
pauseMarker.value.longitude,
location.latitude,
location.longitude
);
pauseMarker.value = {};
return true;
}
return result;
}
// 更新軌跡線
function updatePolyline() {
if (trackPoints.value.length < 2) return;
polyline.value = [
{
points: trackPoints.value.map((point) => ({
latitude: point.latitude,
longitude: point.longitude,
})),
color: '#007AFF',
width: 4,
arrowLine: true,
},
];
}
// 重置狀態(tài)
function resetState() {
trackPoints.value = [];
polyline.value = [];
markers.value = [];
startTime.value = null;
currentTime.value = Date.now(); // 清除時(shí)也重置當(dāng)前時(shí)間
// 重置暫停相關(guān)狀態(tài)
isPause.value = false;
pauseStartTime.value = null;
totalPauseTime.value = 0;
isContinueAfterPause.value = false;
pauseNum.value = 0;
pauseDistance.value = 0;
pauseMarker.value = {};
}
// 停止位置監(jiān)聽
function stopLocationTracking() {
console.log('調(diào)用停止位置監(jiān)聽函數(shù),當(dāng)前狀態(tài):', {
isTracking: isTracking.value,
isPause: isPause.value,
markersCount: markers.value.length,
});
// 防止重復(fù)調(diào)用
if (!isTracking.value) {
console.log('已經(jīng)在停止?fàn)顟B(tài),跳過重復(fù)調(diào)用');
return;
}
uni.stopLocationUpdate({
success: async () => {
console.log('停止監(jiān)聽位置變化成功');
isTracking.value = false;
stopTimer(); // 停止定時(shí)器
// 移除位置變化監(jiān)聽
uni.offLocationChange();
// 重置暫停相關(guān)狀態(tài)
isPause.value = false;
pauseStartTime.value = null;
// 注意:這里不重置 totalPauseTime,因?yàn)橥V褂涗洉r(shí)應(yīng)該保留總暫停時(shí)間用于顯示
// 每次停止記錄時(shí)都添加結(jié)束點(diǎn)標(biāo)記
await getCurrentLocation();
addMarker({
latitude: mapCenter.value.latitude,
longitude: mapCenter.value.longitude,
id: new Date().getTime(),
content: '結(jié)束點(diǎn)',
});
uni.showToast({
title: '已停止記錄',
icon: 'none',
});
},
fail: (err) => {
console.error('停止監(jiān)聽位置變化失敗:', err);
},
});
}
// 保存軌跡記錄
function saveTrack() {
let saveData = {
id: new Date().getTime(),
mapCenter: mapCenter.value,
markers: markers.value,
polyline: polyline.value,
viewModeTotalDistance: totalDistance.value,
viewModeFormatDuration: formatDuration.value,
viewModeAverageSpeed: averageSpeed.value,
};
console.log('保存軌跡記錄', saveData);
let trackData = uni.getStorageSync('trackData') || [];
trackData.push(saveData);
uni.setStorageSync('trackData', trackData);
uni.showToast({
title: '軌跡記錄已保存',
icon: 'success',
});
setTimeout(() => {
uni.reLaunch({
url: `/pages/home/index`,
});
}, 1000);
}
</script>
<style lang="scss" scoped>
.container {
position: relative;
width: 100%;
height: 100vh;
}
.map {
width: 100%;
height: 100%;
}
.operate-box {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
padding: 20rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.mode-panel {
background: rgba(255, 255, 255, 0.95);
border-radius: 12rpx;
padding: 15rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
margin-bottom: 20rpx;
}
.mode-item {
display: flex;
align-items: center;
margin-bottom: 10rpx;
&:last-child {
margin-bottom: 0;
}
}
.mode-label {
font-size: 26rpx;
color: #666;
margin-right: 10rpx;
}
.mode-switch {
display: flex;
align-items: center;
background: #f0f0f0;
border-radius: 15rpx;
padding: 6rpx 10rpx;
switch {
margin: 0 10rpx;
}
}
.mode-text {
font-size: 24rpx;
color: #333;
padding: 4rpx 10rpx;
border-radius: 10rpx;
&.active {
background: #007aff;
color: white;
}
}
.control-panel {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 10rpx;
width: 100%;
}
.control-btn {
padding: 10rpx 20rpx;
background: rgba(255, 255, 255, 0.9);
border: 1px solid #ddd;
border-radius: 22rpx;
font-size: 32rpx;
color: #333;
display: flex;
justify-content: center;
align-items: center;
&.active {
background: #007aff;
color: white;
border-color: #007aff;
}
&:disabled {
opacity: 0.5;
}
}
.pause-btn {
background: rgba(255, 193, 7, 0.9);
color: #fff;
border-color: #ffc107;
&.pause-active {
background: rgba(76, 175, 80, 0.9);
color: white;
border-color: #4caf50;
}
}
.info-panel {
position: absolute;
bottom: 20rpx;
left: 20rpx;
right: 20rpx;
background: rgba(255, 255, 255, 0.95);
border-radius: 12rpx;
padding: 15rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
z-index: 100;
}
.pause-status {
text-align: center;
margin-bottom: 10rpx;
padding: 8rpx;
background: rgba(255, 193, 7, 0.1);
border-radius: 8rpx;
border: 1px solid rgba(255, 193, 7, 0.3);
}
.pause-text {
font-size: 26rpx;
color: #ff9800;
font-weight: 500;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8rpx;
&:last-child {
margin-bottom: 0;
}
}
.info-label {
font-size: 28rpx;
color: #666;
}
.info-value {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
</style>
注意:getSetting 函數(shù)是封裝的權(quán)限授權(quán)功能,查看我的這篇文章:http://m.fzitv.net/javascript/364386r13.htm
總結(jié)
到此這篇關(guān)于uniapp封裝地圖運(yùn)動(dòng)軌跡的文章就介紹到這了,更多相關(guān)uniapp封裝地圖運(yùn)動(dòng)軌跡內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決vue中使用swiper插件問題及swiper在vue中的用法
Swiper是純javascript打造的滑動(dòng)特效插件,面向手機(jī)、平板電腦等移動(dòng)終端。這篇文章主要介紹了解決vue中使用swiper插件及swiper在vue中的用法,需要的朋友可以參考下2018-04-04
解決vue-photo-preview 異步圖片放大失效的問題
這篇文章主要介紹了解決vue-photo-preview 異步圖片放大失效的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
vue如何實(shí)現(xiàn)級(jí)聯(lián)選擇器功能
這篇文章主要介紹了vue如何實(shí)現(xiàn)級(jí)聯(lián)選擇器功能問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Vue+Echarts實(shí)現(xiàn)簡(jiǎn)單折線圖
這篇文章主要為大家詳細(xì)介紹了Vue+Echarts實(shí)現(xiàn)簡(jiǎn)單折線圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue中設(shè)置echarts寬度自適應(yīng)的代碼步驟
這篇文章主要介紹了vue中設(shè)置echarts寬度自適應(yīng)的問題及解決方案,常常需要做到echarts圖表的自適應(yīng),一般是根據(jù)頁(yè)面的寬度做對(duì)應(yīng)的適應(yīng),本文記錄一下設(shè)置echarts圖表的自適應(yīng)的步驟,需要的朋友可以參考下2022-09-09
vue子傳父關(guān)于.sync與$emit的實(shí)現(xiàn)
這篇文章主要介紹了vue子傳父關(guān)于.sync與$emit的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
vue3中使用keepAlive緩存路由組件不生效的問題解決
這篇文章主要介紹了vue3中使用keepAlive緩存路由組件不生效的問題解決,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-06-06
Vuepress生成文檔部署到gitee.io的注意事項(xiàng)及說明
這篇文章主要介紹了Vuepress生成文檔部署到gitee.io的注意事項(xiàng)及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

