arcgis 4.x 入门学习七 (图形动画)
/* arcgis动画计算参数 * graphic 动画图形 * paths 动画轨迹路径 */ let animate = function(pointGraphic,paths,line){ this.line = line; this.timer = null; this.paths = paths; //路径 this.index = 0; //像素帧下标 this.speed = 60; //速度 this.status = 0; //状态 // 0 停止 // 1 运动 this._animate = []; //监听动画的事件集 this.pointGraphic = pointGraphic; //唯一像素图片 this.analysisPaths = []; //像素帧 this.init.apply(this,arguments); } animate.prototype = { // 初始化函数 init (param){ // 开始处理分析路径 this.analysisPath() }, // 开始动画 play (index){ debugger; if( this.status == 1 ){ return //禁止重复播放 } this.status = 1; index && ( this.index = index ) this.animate(); }, // 暂停动画 pause (){ this.status = 0; this.timer && clearTimeout(this.timer); this.timer = null; }, // 重置动画 reset (){ this.pause(); this.index = 0; this.moveGraphic(0) }, // 改变速度 setSpeed (level){ this.speed = level * 60; if( this.status === 1 ){ // 如果正在播放中 this.pause(); this.play(); } }, getSpeed (){ return this.speed / 60; }, /* 分析路径处理 * 将路径分为可置信的几个小段 */ analysisPath (){ var paths = this.paths; var analysisPaths = []; var len = this.speed; for( var i = 0 ; i < paths.length-1 ; i++ ){ var //获取经度 lon = paths[i][0], //获取纬度 lat = paths[i][1]; //开始计算差值 var _lon = (lon - paths[i+1][0])/len; var _lat = (lat - paths[i+1][1])/len; for( var i1 = 0 ; i1 < len; i1++ ){ analysisPaths.push([lon-_lon*i1,lat-_lat*i1]) } } // 将处理好的位置像素帧保存下来 this.analysisPaths = analysisPaths; }, /* 动画过程 * */ animate (){ // this.status = 1; this.timer = setTimeout(()=>{ // 如果运动状态被改为了0 则立即停止 if( this.status === 0 ){ return } this.moveGraphic(this.index++); this.createLine(); if( this.index < this.analysisPaths.length ){ this.animate(); } },1000 / this.speed) }, /** 将点移动到对应下标上 * */ moveGraphic (index){ var point = this.analysisPaths[index]; this.pointGraphic.geometry.x = point[0]; this.pointGraphic.geometry.y = point[1]; this.pointGraphic.geometry = this.pointGraphic.geometry.clone(); this._onAnimate(this); }, /** 渲染轨迹线 * */ createLine() { if( this.line ){ debugger; this.line.geometry.paths[0] = this.analysisPaths.slice(0,this.index); this.line.geometry = this.line.geometry.clone(); } }, _onAnimate (_this){ this._animate.forEach(( e )=>{ try{ e(_this) }catch(e){}; return ; }); }, onAnimate (fn){ if( typeof fn === 'function' ){ this._animate.push(fn); return { remove (){ var index = this._animate.find((e)=> { return e === fn }); this._animate.splice(index,1); } } } } } export default animate;
上面就是封装好的简单代码了 逻辑很简单 看看就能懂
然后上一个实际使用案例
<template>
<div>
<div class='taskNotes'>
<!-- 头部 -->
<div class='taskNotesHead'>
<img :src='require("@/assets/img/Plan/drawLineMap/shebei.png")' />
<span>作业记录详细</span>
</div>
<!-- 作用身体 -->
<div>
<div class='taskInfo'>
<div class='taskInfoModel'>
<div class='taskName'>设备名称:</div>
<div>1号无人喷药车</div>
</div>
<div class='taskInfoModel'>
<div class='taskName'>作业面积:</div>
<div>5.3亩</div>
</div>
<div class='taskInfoModel'>
<div class='taskName'>作业类型:</div>
<div>巡检</div>
</div>
<div class='taskInfoModel'>
<div class='taskName'>总计耗时:</div>
<div>15分钟</div>
</div>
<div class='taskInfoModel'>
<div class='taskName'>开始时间:</div>
<div>2020-10-25 10:35</div>
</div>
<div class='taskInfoModel'>
<div class='taskName'>结束时间:</div>
<div>2020-10-25 10:35</div>
</div>
</div>
</div>
<!-- 尾部 -->
<!-- <div class='footor'> -->
<!-- <div class='save'>预览</div>
<div class='save'>加速</div>
<div class='save'>重置</div> -->
<!-- </div> -->
</div>
<!-- 控制界面 -->
<div class='optControl'>
<div>
<el-slider v-model="index" @change='changeIndex' max='100'></el-slider>
</div>
<div class='controlBox'>
<i class='el-icon-refresh-left' @click='reset'></i>
<i class='el-icon-video-pause' style='color:red;' v-show='status==1' @click='pause'></i>
<i class='el-icon-video-play' style='color:green;' v-show='status==0' @click='play'></i>
<div class='speed' @click='changeSpeed'> x{{speed}} </div>
</div>
</div>
</div>
</template>
<script>
import animate from './js/arcgis_animate';
import { map3d } from 'jiankun_map'
var paths = [[12623867.192992784,2654167.017123362],[12623833.202421965,2654103.115462072],[12623804.1249852,2654046.746480573],[12623777.953436079,2653990.4498262624],[12623752.896882452,2653938.944122552],[12623717.467376597,2653872.9993854314],[12623689.386448707,2653815.950333535],[12623665.734689742,2653756.7947267327],[12623658.737134164,2653685.932486681]];
paths.reverse();
export default {
data() {
return {
index: 0,
speed: 1,
status: 0
}
},
mounted (){
},
methods: {
createAnimate (){
// 路线对象 这里也是自己封装的一个 实际上 就是创建一个线段对象 主要用来实现动画的路线渲染的
var lineGraphic = map3d.Util.createGraphic({
geometry : {
type: "polyline",
hasZ: false,
hasM: true,
paths: [[]],
spatialReference: { wkid: 102100 }
},
symbol : {
type: "simple-line",
color: "lightblue",
width: "2px",
style: "short-dot"
}
});
debugger;
var layer = map3d.Util.addGraphic(lineGraphic,"liaoweizhong")
// 几何对象 这里是用的我自己封装的方法集 实际上就是创建一个点Graphic
var pointGraphic = map3d.Util.createImgPoint({
img: require("@/assets/img/Plan/biaoshi.png"),
xy: paths[0],
spatialReference: { wkid: 102100 }
});
var layer = map3d.Util.addGraphic(pointGraphic,"liaoweizhong")
// 创建点动画
this.animate = new animate(pointGraphic,paths,lineGraphic); this.animate.onAnimate((res)=>{
this.status = res.status;
this.index = parseInt((res.index + 1) / res.analysisPaths.length * 100);
if( this.index === 100 ){
this.pause();
}
})
},
pause (){
this.status = 0
this.animate.pause();
},
play (){
if( this.index === 100 ) {
this.reset();
}
this.animate.play();
},
reset (){
this.animate.reset();
},
changeIndex (){
this.animate.index = parseInt(this.animate.analysisPaths.length * (this.index / 100));
this.animate.moveGraphic(this.animate.index);
},
changeSpeed (){
var level = this.animate.getSpeed();
level++;
if( level > 3 ){
level = 1;
}
this.animate.setSpeed(level);
debugger;
this.speed = level;
}
}
}
</script>
<style scoped>
.taskNotes {
position: absolute;
top: 50px;
right: 15px;
background: #00000080;
width: 185px;
border-radius: 6px;
color: #fff;
padding: 8px;
}
.taskNotesHead {
padding-bottom: 8px;
margin-bottom: 8px;
}
.taskNotesHead img {
width: 12px;
}
.taskInfoModel {
display: flex;
padding: 6px 0px;
}
.taskInfo {
color: #ffffff;
}
.taskName {
width: 65px;
flex-shrink: 0;
}
.footor {
display: flex;
justify-content: space-between;
padding: 9px 0;
font-size: 12px;
margin-top: 10px;
}
.save {
padding: 6px 12px;
background: #35a24c;
border-radius: 4px;
color: #ffffff;
font-size: 12px;
cursor: pointer;
}
.close {
padding: 6px 12px;
background: #ffffff;
border-radius: 4px;
color: #4e4d4d;
font-size: 12px;
cursor: pointer;
}
.optControl {
position:absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
width: 300px;
padding: 15px;
border-radius: 4px;
background: #000000A8;
color: #fff;
}
.controlBox {
display: flex;
justify-content: space-evenly;
font-size: 22px;
}
.controlBox i {
cursor: pointer;
}
.speed {
font-size: 12px;
border-radius: 50%;
border: solid 2px #fff;
padding: 0 0px;
width: 21px;
text-align: center;
line-height: 18px;
}
</style>

浙公网安备 33010602011771号