天天看點

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類,還多出來了query和on這倆,字面意思可以猜測是查詢和事件有關。繼續往下看。

 為了實作動畫移動錄影機,就要在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添加事件:

ArcGIS API for JavaScript 4.2學習筆記[6] goTo()地圖動畫
ArcGIS API for JavaScript 4.2學習筆記[6] goTo()地圖動畫
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中定義的按鈕元素後添加了事件以及函數體後,自然就是為它添加動畫效果了。

我們取完整函數體看看,有什麼異同。

ArcGIS API for JavaScript 4.2學習筆記[6] goTo()地圖動畫
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查詢,我簡單列出這幾個枚舉:

linear

in-cubic

out-cubic

in-out-cubic

in-expo

out-expo

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

繼續閱讀