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>

 

上一篇:在vue中使用animate.css动画插件


下一篇:Animate.css的简单使用