這是個很有意思的例子,不過例子給的比較複雜,需要查很多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添加事件:

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查詢,我簡單列出這幾個枚舉:
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可以解決,本文隻是解讀官方的例子達到入門效果。