概要
対象
- 実際に公開するページ(ride.html)で動く以下Javascript
- インラインでコメントしながら理解する
js/esri-map.js
- 地図上でピンやUnicorn画像を動かすための処理
- Tokenなどの処理はなかった
全体
/*global WildRydes _config*/
// グローバル変数「WildRydes」を定義。定義済みだったら定義済みの変数を使う
var WildRydes = window.WildRydes || {};
// 「WildRydes」のmapオブジェクトを定義。こちらも同じく定義済みだったら定義済みの変数を使う
WildRydes.map = WildRydes.map || {};
// ()でくくってあるので、読み込みと同時に実行される即時関数
(function esriMapScopeWrapper($) {
...
}(jQuery));
require.js
// esriのモジュールをrequireして、requireCallback()を実行する
require([
'esri/Map',
'esri/views/MapView',
'esri/Graphic',
'esri/geometry/Point',
'esri/symbols/TextSymbol',
'esri/symbols/PictureMarkerSymbol',
'esri/geometry/support/webMercatorUtils',
'dojo/domReady!'
], function requireCallback(
...
) {
...
});
requireCallback()
function requireCallback(
// 引数はrequireしたオブジェクト達
Map, MapView,
Graphic, Point, TextSymbol,
PictureMarkerSymbol, webMercatorUtils
) {
// グローバル変数のmapオブジェクト
var wrMap = WildRydes.map;
// 「gray-vector」っていうフリーのマップを使ってmapオブジェクト生成
var map = new Map({ basemap: 'gray-vector' });
// 地図表示用オブジェクト生成
var view = new MapView({
center: [-122.31, 47.60],
container: 'map',
map: map,
zoom: 12
});
// 地図上に配置するピンのオブジェクト生成
var pinSymbol = new TextSymbol({
color: '#f50856',
text: '\ue61d',
font: {
size: 20,
family: 'CalciteWebCoreIcons'
}
});
// ピンに向かってくるUnicornのオブジェクト生成
var unicornSymbol = new PictureMarkerSymbol({
url: 'images/unicorn-icon.png',
width: '25px',
height: '25px'
});
var pinGraphic;
var unicornGraphic;
// 与えられた緯度経度を地図の中心に持ってくる
function updateCenter(newValue) {
wrMap.center = {
latitude: newValue.latitude,
longitude: newValue.longitude
};
}
// 与えられた数値を基に、表示領域の更新
function updateExtent(newValue) {
var min = webMercatorUtils.xyToLngLat(newValue.xmin, newValue.ymin);
var max = webMercatorUtils.xyToLngLat(newValue.xmax, newValue.ymax);
wrMap.extent = {
minLng: min[0],
minLat: min[1],
maxLng: max[0],
maxLat: max[1]
};
}
// 地図を表示
view.watch('extent', updateExtent);
view.watch('center', updateCenter);
view.then(function onViewLoad() {
updateExtent(view.extent);
updateCenter(view.center);
});
// 地図上でクリックされたら、eventを取得してhandleViewClick()を実行
view.on('click', function handleViewClick(event) {
// 地図上のクリックした地点を取得
wrMap.selectedPoint = event.mapPoint;
// ピンを削除
view.graphics.remove(pinGraphic);
// クリックした地点に新しいピンを生成
pinGraphic = new Graphic({
symbol: pinSymbol,
geometry: wrMap.selectedPoint
});
// 地図に新しいピンを追加
view.graphics.add(pinGraphic);
// 「pickupCahge」eventを発生させる
// event発生時の処理はride.jsのhandlePickupChanged()
$(wrMap).trigger('pickupChange');
});
// アニメーション関数オブジェクト生成
wrMap.animate = function animate(origin, dest, callback) {
// 開始時刻
var startTime;
// animateFrame()関数を変数に入れる
var step = function animateFrame(timestamp) {
var progress;
var progressPct;
var point;
var deltaLat;
var deltaLon;
// 開始時刻がなければ現在時刻を設定
if (!startTime) startTime = timestamp;
// 経過時間
progress = timestamp - startTime;
// 「経過時間/2000」と「1」の小さい方
progressPct = Math.min(progress / 2000, 1);
// 移動先と現在地の緯度経度の差分に上記計算したprogressPctを乗算
deltaLat = (dest.latitude - origin.latitude) * progressPct;
deltaLon = (dest.longitude - origin.longitude) * progressPct;
// 移動先の地点のオブジェクトを生成
point = new Point({
longitude: origin.longitude + deltaLon,
latitude: origin.latitude + deltaLat
});
// Unicorn画像情報を削除
view.graphics.remove(unicornGraphic);
// 新しい位置情報を持ったUnicorn画像を生成
unicornGraphic = new Graphic({
geometry: point,
symbol: unicornSymbol
});
// Unicorn画像を追加
view.graphics.add(unicornGraphic);
// progressPctが1以下の場合、ブラウザ上でアニメーションを行う
// @see https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame
if (progressPct < 1) {
requestAnimationFrame(step);
} else {
callback();
}
};
// ブラウザ上でアニメーションを行う
requestAnimationFrame(step);
};
// 位置情報が設定されていない場合、ピンを削除
wrMap.unsetLocation = function unsetLocation() {
view.graphics.remove(pinGraphic);
};
}
参考にさせてもらったページ
今回の収穫
- グローバル変数の定義方法
- require.jsでfunctionで使うmoduleを管理する