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可以解決,本文只是解讀官方的例子達到入門效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM