当前位置: 首页 > news >正文

北京网站设计我选柚米免费网站申请域名

北京网站设计我选柚米,免费网站申请域名,网站开发前后端分离,谈谈网站开发流程前言 本篇文章主要介绍高德地图的轨迹回放或播放的实现过程,是基于vue2实现的功能,同时做一些改动也是能够适配vue3的。其中播放条是用的是element UI中的el-slider组件,包括使用到的图标也是element UI自带的。可以实现轨迹的播放、暂停、停…

前言

本篇文章主要介绍高德地图的轨迹回放或播放的实现过程,是基于vue2实现的功能,同时做一些改动也是能够适配vue3的。其中播放条是用的是element UI中的el-slider组件,包括使用到的图标也是element UI自带的。可以实现轨迹的播放、暂停、停止、播放倍数,以及播放拖拽,涉及到的高德地图的相关权限申请,这里就不再赘述,好了,废话不多说,效果图附上。

效果图 


一、地图初始化

首先,需要在组件dom加载完毕后初始化地图,这里小谭直接用的new AMap.Map方法进行初始化,需要在index.html引入高德的服务。

<script src="https://webapi.amap.com/maps?v=2.0&key=你的key"></script>

其次,在引入高德服务之后,需要在单独引入高德AMapUI 组件库,因为轨迹播放是基于该组件库实现的,引入示例:

<!--引入UI组件库(1.1版本) -->
<script src="//webapi.amap.com/ui/1.1/main.js"></script>

最后,就可以进行初始化地图了,注意需要在组件dom加载完毕才能进行初始化!其中this.map是地图实例,附上代码:

 this.map = new AMap.Map('myMap', {zoom: 10, //级别center:[120.209758, 30.246809], //中心点坐标 默认在杭州});

二、轨迹插件初始化

在地图初始化完成之后,可以引入一些需要的插件,这里就不再过多赘述,我们直接引入AMapUI,我们这里用到的是PathSimplifier模块,故只需要引入该模块即可,附上代码:

//加载PathSimplifier,loadUI的路径参数为模块名中 'ui/' 之后的部分
new AMapUI.load(['ui/misc/PathSimplifier'], PathSimplifier => {if (!PathSimplifier.supportCanvas) {alert('当前环境不支持 Canvas!');return;}if (this.pathList?.length) {//启动页面this.initPage(PathSimplifier);}
});

其中,涉及到的this.pathList是我这边后端返回坐标点信息,this.pathList结构如下:

this.pathList = [[120.79580028, // 经度30.03570354 // 纬度],...];

this.initPage方法如下,需要注意的是,方法内声明的content是轨迹播放时展示的车辆图标,如果不需要可以删掉,PathSimplifier中的配置请参照高德地图轨迹展示的开发文档,还有方法最后调用的this.cruiseInit方法已经放到下一部分了。

initPage(PathSimplifier) {let content = PathSimplifier.Render.Canvas.getImageContent('/img/car1.png',() => {//图片加载成功,重新绘制一次this.pathSimplifierIns.renderLater();},function onerror(e) {this.$message({ type: 'error', message: '图片加载失败!' });});this.pathSimplifierIns = new PathSimplifier({zIndex: 100,map: this.map,getPath: function (pathData, pathIndex) {return pathData.path;},renderOptions: {//轨迹线的样式getPathStyle: (pathItem, zoom) => {return {pathLineStyle: {strokeStyle: "red",lineWidth: 6,dirArrowStyle: true,},};},pathNavigatorStyle: {initRotateDegree: 180,width: 20,height: 35,autoRotate: true,content,},},});this.cruiseInit(); //巡航器初始化
}

三、巡航器初始化

巡航器初始化方法this.cruiseInit代码如下:

cruiseInit() {let pathSimplifierIns = [{ path: this.pathList, color: '#28F' }];this.pathSimplifierIns.setData(pathSimplifierIns);this.pointSum = 0;pathSimplifierIns.forEach((item, index) => {this.pointSum += item.path.length;});this.marksIndex = marksIndex;this.cruiseStop();//如果已经存在巡航器,则停止播放
}

其中this.pointSum是为了记录巡航器的最终点数,方便对应到播放条的最大值。


四、巡航器的播放暂停等功能

巡航器的播放、暂停以及倍数的方法如下:

// 创建一个巡航器
createdCruise(index) {// 判断是否传入indexlet cruiseIndex;if (index != undefined) {cruiseIndex = index;this.cruiseIndex = index;} else {cruiseIndex = this.cruiseIndex;}let cruise = this.pathSimplifierIns.createPathNavigator(cruiseIndex, //关联第index条轨迹{loop: false, //循环播放speed: this.speedList[this.speedValue].speed, //速度});if (this.cruise) {// 清空走过的路线this.cruise.destroy();this.cruise = null;}return cruise;
},
// 开始播放
cruiseStart() {this.isPlay = true;if (this.cruise && !this.cruise.isCursorAtPathEnd() && !this.cruise.isCursorAtPathStart() && !this.isComplete) {// 路段未开始并且没有结束的时候 暂停恢复动画 并且动画没有完成的时候this.cruise.resume();return;}this.isComplete = false;if (this.cruiseIndex == 0) {this.cruiseStop();return;}this.cruise = this.createdCruise();// 判断是否传入初始坐标if (this.startPoint) {this.cruise.start(this.startPoint);this.startPoint = 0;} else {this.cruise.start();}this.cruise.on('move', e => {let idx = this.cruise.cursor.idx;let { address, gpsTime, speed } = this.pathList[idx];let trackAddress = {address,gpsTime,speed,};this.$emit('changeData', 'trackAddress', trackAddress);let [min, max] = this.marksIndex[this.cruiseIndex];this.sliderValue = idx + min;});// 巡航完成事触发this.cruise.on('pause', () => {if (this.cruise && this.cruise.isCursorAtPathEnd()) {this.cruiseStart();}});
},// 暂停播放
cruisePause() {this.cruise.pause();this.isPlay = false;
},
// 停止播放
cruiseStop() {if (this.cruise) {// 清空走过的路线this.cruise.destroy();}// 停止播放this.isPlay = false;this.isComplete = true;this.cruiseIndex = -1;// 为重新播放准备this.cruise = this.createdCruise();this.cruiseIndex = -1;this.sliderValue = 0;
},
// 速度改变
speedChange() {if (this.speedValue == this.speedList.length - 1) {this.speedValue = 0;} else {this.speedValue++;}this.cruise.setSpeed(this.speedList[this.speedValue].speed);
},

到这里巡航器的基础功能已经实现,还有一部分关于播放器调整对应轨迹改变,这里我们要用的监听器,即vue的watch属性:


五、变量声明以及HTML结构

其中使用到的变量有这些:

data() {return {    // 地图实例map: null,cruise: null, //巡航器实例cruiseIndex: -1, // 当前播放轨迹下标pathSimplifierIns: null, //轨迹实例isPlay: false, //是否播放isComplete: true, //是否完成pointSum: 0, //播放器总数sliderValue: 0, //播放器当前数startPoint: 0, //下次播放轨迹从当前值开始marksIndex: {}, //每段路的起止坐标pathList: [],// 轨迹坐标speedValue: 3,// 当前播放速度下标// 速度列表,可自定义配置speedList: [{ value: 0.5, speed: 100 },{ value: 1, speed: 200 },{ value: 2, speed: 400 },{ value: 4, speed: 1600 },{ value: 8, speed: 12800 },{ value: 16, speed: 25600 },],};
},

HTML结构:

<template><div class="workTrack"><div id="myMap"></div><div class="sliderBar" v-show="pathList.length"><span @click="cruiseStart()" v-if="!isPlay"><i class="el-icon-video-play"></i></span><span @click="cruisePause" v-else><i class="el-icon-video-pause"></i></span><span @click="cruiseStop"><i class="el-icon-error"></i></span><el-slider :disabled="isPlay" v-model="sliderValue" :max="pointSum" :show-tooltip="false"></el-slider><b @click="speedChange"><i class="el-icon-d-arrow-right"></i><span>×{{ speedList[speedValue].value }}</span></b></div></div>
</template>

css:

.workTrack {width: 100%;position: relative;height: 100%;#myMap {width: 100%;height: 100%;}.sliderBar {position: absolute;bottom: 30px;user-select: none;width: 100%;padding: 10px 2%;background-color: #00000064;border-radius: 400px;backdrop-filter: blur(5px);z-index: 99;width: 80%;right: 0;left: 0;margin: auto;display: flex;justify-content: center;align-items: center;.el-slider {flex: 1;transform: translateY(1px);margin: 0 15px;}::v-deep .el-slider__runway {pointer-events: none;background-color: #00000021;margin: 0;.el-slider__bar {background-color: #1682e6;}.el-slider__stop {background-color: #1682e6;border-radius: 0;width: 2px;}.el-slider__button-wrapper {pointer-events: auto;}.el-slider__marks-text {white-space: nowrap;color: #fff;font-size: 0;}}> span {flex-shrink: 0;transform: translateY(1px);color: #eee;cursor: pointer;margin: 0 5px;transition: 0.3s;font-size: 20px;&:hover {opacity: 0.5;}}> b {flex-shrink: 0;color: #eee;font-weight: normal;margin: 0 5px;cursor: pointer;border-radius: 3px;border: 1px solid #eee;padding: 0px 10px;transition: 0.3s;user-select: none;> span {vertical-align: middle;font-size: 14px;display: inline-block;transform: translateY(-2px);}i {vertical-align: middle;font-size: 16px;display: inline-block;transform: translateY(-1px);}&:hover {opacity: 0.5;}}}}

六:完整代码

完整代码如下:

<!-- * @description 轨迹回放* @fileName: track.vue * @author: tan * @date: 2024-06-17 10:02:28
!-->
<template><div class="workTrack"><div id="myMap"></div><div class="sliderBar" v-show="pathList.length"><span @click="cruiseStart()" v-if="!isPlay"><i class="el-icon-video-play"></i></span><span @click="cruisePause" v-else><i class="el-icon-video-pause"></i></span><span @click="cruiseStop"><i class="el-icon-error"></i></span><el-slider :disabled="isPlay" v-model="sliderValue" :max="pointSum" :show-tooltip="false"></el-slider><b @click="speedChange"><i class="el-icon-d-arrow-right"></i><span>×{{ speedList[speedValue].value }}</span></b></div></div>
</template><script>
export default {data() {return {// 地图实例map: null,cruise: null, //巡航器实例cruiseIndex: -1, // 当前播放轨迹下标pathSimplifierIns: null, //轨迹实例isPlay: false, //是否播放isComplete: true, //是否完成pointSum: 0, //播放器总数sliderValue: 0, //播放器当前数startPoint: 0, //下次播放轨迹从当前值开始marksIndex: {}, //每段路的起止坐标// 轨迹坐标pathList: [// [经度,纬度] 可再次放置测试数据[120.79573938, 30.03576463],],speedValue: 3, // 当前播放速度下标// 速度列表,可自定义配置speedList: [{ value: 0.5, speed: 100 },{ value: 1, speed: 200 },{ value: 2, speed: 400 },{ value: 4, speed: 1600 },{ value: 8, speed: 12800 },{ value: 16, speed: 25600 },],};},mounted() {this.map = new AMap.Map('myMap', {zoom: 10, //级别center: [120.209758, 30.246809], //中心点坐标 默认在杭州});this.$nextTick(() => {this.loadMap();});},methods: {// 加载地图loadMap() {return new Promise((reslove, reject) => {//加载PathSimplifier,loadUI的路径参数为模块名中 'ui/' 之后的部分new AMapUI.load(['ui/misc/PathSimplifier'], PathSimplifier => {if (!PathSimplifier.supportCanvas) {alert('当前环境不支持 Canvas!');return;}if (this.pathList?.length) {//启动页面this.initPage(PathSimplifier);}});reslove();});},initPage(PathSimplifier) {let content = PathSimplifier.Render.Canvas.getImageContent('/img/car1.png',() => {//图片加载成功,重新绘制一次this.pathSimplifierIns.renderLater();},function onerror(e) {this.$message({ type: 'error', message: '图片加载失败!' });});this.pathSimplifierIns = new PathSimplifier({zIndex: 100,map: this.map,getPath: function (pathData, pathIndex) {return pathData.path;},renderOptions: {//轨迹线的样式getPathStyle: (pathItem, zoom) => {return {pathLineStyle: {strokeStyle: 'red',lineWidth: 6,dirArrowStyle: true,},};},pathNavigatorStyle: {initRotateDegree: 180,width: 20,height: 35,autoRotate: true,content,},},});this.cruiseInit();},// 巡航器初始化cruiseInit() {let pathSimplifierIns = [{ path: this.pathList, color: '#28F' }];this.pathSimplifierIns.setData(pathSimplifierIns);this.pointSum = 0;let marksIndex = {};pathSimplifierIns.forEach((item, index) => {this.pointSum += item.path.length;marksIndex[index] = [0, this.pointSum];});this.marksIndex = marksIndex;this.cruiseStop();},// 创建一个巡航器createdCruise(index) {this.cruiseIndex++;// 判断是否传入indexlet cruiseIndex;if (index != undefined) {cruiseIndex = index;this.cruiseIndex = index;} else {cruiseIndex = this.cruiseIndex;}let cruise = this.pathSimplifierIns.createPathNavigator(cruiseIndex, //关联第index条轨迹{loop: false, //循环播放speed: this.speedList[this.speedValue].speed, //速度});if (this.cruise) {// 清空走过的路线this.cruise.destroy();this.cruise = null;}return cruise;},// 开始播放cruiseStart() {this.isPlay = true;if (this.cruise && !this.cruise.isCursorAtPathEnd() && !this.cruise.isCursorAtPathStart() && !this.isComplete) {// 路段未开始并且没有结束的时候 暂停恢复动画 并且动画没有完成的时候this.cruise.resume();return;}this.isComplete = false;if (this.cruiseIndex == 0) {this.cruiseStop();return;}this.cruise = this.createdCruise();// 判断是否传入初始坐标if (this.startPoint) {this.cruise.start(this.startPoint);this.startPoint = 0;} else {this.cruise.start();}this.cruise.on('move', e => {let idx = this.cruise.cursor.idx;let { address, gpsTime, speed } = this.pathList[idx];let trackAddress = {address,gpsTime,speed,};this.$emit('changeData', 'trackAddress', trackAddress);let [min, max] = this.marksIndex[this.cruiseIndex];this.sliderValue = idx + min;});// 巡航完成事触发this.cruise.on('pause', () => {if (this.cruise && this.cruise.isCursorAtPathEnd()) {this.cruiseStart();}});},// 暂停播放cruisePause() {this.cruise.pause();this.isPlay = false;},// 停止cruiseStop() {if (this.cruise) {// 清空走过的路线this.cruise.destroy();}// 停止播放this.isPlay = false;this.isComplete = true;this.cruiseIndex = -1;// 为重新播放准备this.cruise = this.createdCruise();this.cruiseIndex = -1;this.sliderValue = 0;},speedChange() {if (this.speedValue == this.speedList.length - 1) {this.speedValue = 0;} else {this.speedValue++;}this.cruise.setSpeed(this.speedList[this.speedValue].speed);},},watch: {sliderValue(val) {// 正在播放禁止拖拽播放器if (!this.cruise || this.isPlay) return;this.cruise.moveToPoint(val);this.startPoint = val;this.pathSimplifierIns.render();},},beforeDestroy() {if (this.pathSimplifierIns) this.pathSimplifierIns.clearPathNavigators();if (this.pathSimplifierIns) this.pathSimplifierIns.setData([]);if (this.cruise) this.cruise.destroy();if (this.map) this.map.destroy();},
};
</script><style lang="scss" scoped>
.workTrack {width: 100%;position: relative;height: 100%;#myMap {width: 100%;height: 100%;}.sliderBar {position: absolute;bottom: 30px;user-select: none;width: 100%;padding: 10px 2%;background-color: #00000064;border-radius: 400px;backdrop-filter: blur(5px);z-index: 99;width: 80%;right: 0;left: 0;margin: auto;display: flex;justify-content: center;align-items: center;.el-slider {flex: 1;transform: translateY(1px);margin: 0 15px;}::v-deep .el-slider__runway {pointer-events: none;background-color: #00000021;margin: 0;.el-slider__bar {background-color: #1682e6;}.el-slider__stop {background-color: #1682e6;border-radius: 0;width: 2px;}.el-slider__button-wrapper {pointer-events: auto;}.el-slider__marks-text {white-space: nowrap;color: #fff;font-size: 0;}}> span {flex-shrink: 0;transform: translateY(1px);color: #eee;cursor: pointer;margin: 0 5px;transition: 0.3s;font-size: 20px;&:hover {opacity: 0.5;}}> b {flex-shrink: 0;color: #eee;font-weight: normal;margin: 0 5px;cursor: pointer;border-radius: 3px;border: 1px solid #eee;padding: 0px 10px;transition: 0.3s;user-select: none;> span {vertical-align: middle;font-size: 14px;display: inline-block;transform: translateY(-2px);}i {vertical-align: middle;font-size: 16px;display: inline-block;transform: translateY(-1px);}&:hover {opacity: 0.5;}}}
}
</style>
http://www.hkea.cn/news/515285/

相关文章:

  • 装修设计网站哪个平台最好软文推广多少钱一篇
  • 怎么做微信里的网页网站链接网站设计平台
  • 长宁专业做网站网络营销案例分享
  • 哈尔滨专业建网站哪家好码迷seo
  • 涞水县住房和城乡建设局网站厦门seo专业培训学校
  • 网站建设销售招聘德阳seo
  • 平台网站建设的公司seozou是什么意思
  • wordpress 相册 主题seo整站优化技术培训
  • 做窗帘网站图片百度自动点击器下载
  • 飘雪影视大全免费观看视频快推达seo
  • 做网站的装饰标语seo宣传网站
  • 国外 平面设计 网站百度收录
  • 做网站话术简述搜索引擎的工作原理
  • 现在建设网站赚钱吗seo外链论坛
  • 青海网站建设企业海南百度竞价推广
  • 南京做网站yuanmus电脑突然多了windows优化大师
  • 美国做deals的网站软文营销经典案例优秀软文
  • 招标网站怎么做吴江seo网站优化软件
  • 苏州建设工程协会网站seo去哪里学
  • 上海正规网站制作价格可口可乐软文营销案例
  • 番禺网站 建设信科网络站长之家ping
  • 建筑工程施工承包合同关键词优化报价推荐
  • 网站可以免费看企业网站系统
  • 中华人民共和国建设部网站seo怎么快速提高排名
  • 南宁做网站的有几家东莞网络营销网站建设
  • 苏州知名网站建设开发新区seo整站优化公司
  • 政府建设网站计划书品牌营销策略包括哪些内容
  • 深圳市做网站百度seo排名点击器app
  • 五莲网站建设维护推广网络营销推广及优化方案
  • 重庆网红整站多关键词优化