zoukankan      html  css  js  c++  java
  • ArcGIS API for JavaScript 4.2学习笔记[6] goTo()地图动画

    这是个很有意思的例子,不过例子给的比较复杂,需要查很多API,我会在文章最后给出关键的类和属性解释。

    同样发现一个很有意思的事儿:博客园似乎有爬虫,我4号发布的blogs,5号就在百度和google搜索页面上看到了转载或者复制。

    这篇文章逻辑组织不太好,想知道怎么做缩放动画的可以直接拉到尾部看结论。

    当然,这篇代码比较多,不建议手机看。


    进入正题,goTo()动画,官方的例子是在SceneView中实现的。

    照例,给出require的第一个字符串数组参数

    require(
      [
        "esri/Map",
        "esri/views/SceneView",
        "dojo/query",
        "dojo/on"
        "dojo/domReady!"
      ]
      function(Map,SceneView,query,on)
      {
        //你的代码
      }
    );

     除了上一次熟悉的Map类SceneView类,还多出来了queryon这俩,字面意思可以猜测是查询和事件有关。继续往下看。

     为了实现动画移动摄像机,就要在html页面组织一些按钮。

     于是,在html的body标签内如下组织:

    <body>
      <div id="optionsDiv">
        <button id="default">Default flight</button>
        <button id="linearSlow">Linear slow flight</button>
        <button id="linearFast">Linear fast flight</button>
        <button id="expoIncrease">Exponentially increasing speed flight</button>
        <button id="fixedDuration">10 seconds flight</button>
        <button id="bounceBerlin">Bounce to Berlin</button>
      </div>
      <div id="viewDiv"></div>
    </body>

    6个按钮,分别是:默认漫游、较慢漫游、较快漫游、渐渐加快漫游、10秒钟漫游、弹性缩放到柏林

    于是,在require的第二个函数参数里,就这样给这些button添加事件:

    funtion(Map,SceneView,query,on)
    {
        // 仍然是实例化两个对象,map和view
        var map = new Map({
            basemap: "osm"
        });
        var view = new SceneView({
              container: "viewDiv",
              map: map,
              zoom: 4
        });
    
        on(dojo.query("#default"), "click", function(){
        
        });    
        on(dojo.query("#linearSlow"), "click", function(){
        
        });   
        on(dojo.query("#linearFast"), "click", function(){
        
        });   
        on(dojo.query("#expoIncrease"), "click", function(){
        
        });   
        on(dojo.query("#fixedDuration"), "click", function(){
        
        });
        on(dojo.query("#bounceBerlin"), "click", function(){
        
        });
    )
    函数参数

    仅仅是一个on(dojo.query(), , function(){})方法即可实现为DOM元素添加对应的事件。这里,指定了“click”事件。

    关于dojo.query(),参考博客自 - http://blog.csdn.net/dojotoolkit/article/details/6265337

    这里借用了CSS的语法,dojo.query("#default"),这样就能获取到元素了.

    需要注意的是query方法获取到的是数组,如果只有一个那就是它本身。

    单个按ID查找DOM元素的方法是dojo.byId()


     

    我们继续。获取html中定义的按钮元素后添加了事件以及函数体后,自然就是为它添加动画效果了。

    我们取完整函数体看看,有什么异同。

            on(dojo.query("#default"), "click", function() {
              view.goTo(shiftCamera(60));
            });
    
            on(dojo.query("#linearSlow"), "click", function() {
              view.goTo(shiftCamera(60),
                {
                  speedFactor: 0.1,
                  easing: "linear"
                });
            });
    
            on(dojo.query("#linearFast"), "click", function() {
              view.goTo(shiftCamera(60),
                {
                  speedFactor: 6,
                  easing: "linear"
                });
            });
    
            on(dojo.query("#expoIncrease"), "click", function() {
              view.goTo(shiftCamera(60),
                {
                  duration: 4000,
                  easing: "in-expo"
                });
            });
    
            on(dojo.query("#fixedDuration"), "click", function() {
              view.goTo(shiftCamera(30),
              {
                duration: 10000,
                maxDuration: 10000 
              });
            });
    
            // 自定义时间函数体
            function customEasing(t) {
              return 1 - Math.abs(Math.sin(-1.7 + t * 4.5 * Math.PI)) * Math.pow(
                0.5, t * 10);
            }
    
            on(dojo.query("#bounceBerlin"), "click", function() {
              view.goTo({
                position: {
                  x: 13.40,
                  y: 52.52,
                  z: 700000,
                  spatialReference: {
                    wkid: 4326
                  }
                },
                heading: 0,
                tilt: 0
              }, {
                speedFactor: 0.3,
                easing: customEasing
              });
            });
    click事件函数体

    我们可以发现有很多东西是多出来的。以默认漫游按钮为切入点,发现使用了view这个对象的goTo()方法,参数未知,看来是一个有返回值的方法。查看官方API和本例代码得知goTo()方法和shiftCamera()方法的含义:

    goTo()方法

    将视图转移到给定的目标。参数可以是:Geometry或Geometry数组、Graphic或Graphic数组、Viewpoint对象、Camera对象。

    本例中就使用了Camera对象(shiftCamera方法的返回值就是一个Camera)或Object对象(缩放到柏林)。

    以上的参数是“target”,即目标。

    后面还有一些可选的参数,用{}括起来作为一个Object对象:

    animate(boolean)、speedFactor(number类型)、duration(numer类型)、maxDuration(number类型)、easing(string或方法体)

    speedFactor是速度因子,很好理解,默认是1.

    duration是持续时间,如果有这个,那么speedFactor就会被覆盖。

    maxDuration是最大持续时间。

    easing是缓动方式。

    通常,easing必选,speedFactor和duration、maxDuration三选一。

    参数均可选。

    shiftCamera()方法

    代码如下:

    function shiftCamera(deg){
         var camera = view.camera.clone();
         camera.position.longitude += deg;
         return camera;
    }

    给定一个deg(旋转角,角度制),camera的position的longitude值加上deg值。当然,deg要和longitude类型一样。

    position是一个空间点(Point类,继承自Geometry),longitude是经度。AJS4.2是默认用Web Mercator或WGS 84参考系的。

    本例中默认漫游传入了60度,即每次按按钮就会把视角旋转60度。


     

    我们再来看看第2-第5个漫游按钮。

    它们除了shiftCamera方法返回的Camera对象(target)外,还多了一个{}Object对象(option)。

    本例中,除了弹性缩放到柏林这个按钮外,其余都是用Camera对象和Object对象组合的方式,达到动画效果。

    我们当然可以直接用{}来定义一个Camera对象,就像弹性缩放到柏林这个按钮的方法体内写的。

            on(dojo.query("#bounceBerlin"), "click", function(){
              view.goTo({             //这一层大括号定义的是Camera对象
                position:
                {           //这一层大括号定义的是Camera的position属性
                  x: 13.40,
                  y: 52.52,
                  z: 700000,
                  spatialReference:
                  {            //这一层是空间参考
                    wkid: 4326
                  }
                },
                heading: 0,        //Camera.heading
                tilt: 0           //Camera.tilt
              },
              {      //这一层大括号就是跟上面类似的Object对象了
                speedFactor: 0.3,
                easing: customEasing
              });//这个小括号结束的是goTo的范围
            });

    在Object对象中,easing参数可以指定为一个方法体(返回值是number即可)。这里customEasing就是这样的一个方法。(看起来略复杂)

    function customEasing(t) {
         return 1 - Math.abs(Math.sin(-1.7 + t * 4.5 * Math.PI)) * Math.pow(0.5, t * 10);
    }

    (插一句:如果在C#中,可不能随便这样给个方法名就行了,要用委托才能操作方法)

    关于easing这个参数的string值,大家可以自行到API查询,我简单列出这几个枚举:

    linearin-cubicout-cubicin-out-cubicin-expoout-expoin-out-expo

    都可以自己试试,估计就是速度的不同而已。官方推荐小于1s的动画就用自己定义的方法体,超过1s的就用上面的枚举就行了。


     

    总结。

    地图缩放动画的核心就是view对象的goTo()方法的使用。

    goTo()方法在MapView类和SceneView类中都有提供,但是在它们的父类View类中没有。

    本文就对官方的API和例子进行学习,主要了解goTo()方法的参数的使用。

    用法:view对象.goTo(target, option);

    可以是:{定义Camera对象}+{Option参数}传入(前5个按钮)

    也可以是:直接传一个Camera对象+{Option参数}(最后一个按钮)。

    Option参数中的easing是“必选”的(不然就没动画效果了呀),speedFactor、duration、maxDuration是三选一。

    Camera对象可以自己用方法体返回,也可以直接用js的大括号定义。

    改变Camera对象的一些属性值,如经纬度,就可以达到改变视角。

    至于其他的,如Geometry、Graphic、Viewpoint就没有进行学习了,参考API可以解决,本文只是解读官方的例子达到入门效果。

  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/onsummer/p/6388084.html
Copyright © 2011-2022 走看看