「Kanon」横浜探訪記 JavaScript
■「咲-Saki-」舞台探訪記事の捕捉感謝。
Temporary Feeling さん
>今となっては平安堂すら懐かしいー。
まさか、そういう反応があるとは思ってもみませんでした(笑)
カトゆー家断絶 さん
以上、捕捉出来た限りですが、ありがとうございました。
■京アニ「Kanon」横浜探訪記 JavaScript公開(長文注意)
「Kanon」横浜探訪記が難航中のためのお茶にごし企画。
今回から探訪記で使用しているGoogle Maps APIのJavaScriptに手を加えてみたので、それを公開します。
1.データ部の作成
今まではJavaScrptプログラムの中に直接、マップの位置データ,情報ウィンドウ内のコメント等を埋め込んでいましたが、今回作成効率を上げるために、データ部分を分離することにしました。
分離するデータは、JSON形式とします。JSONと聞くと難しいような気がしますが、中身は単にJavaScriptの配列(構造体)記述と同じ形式です。シンプルでいながら、ハッシュ配列も使える強力な仕様です。
「諸君、私はExcelが好きだ」、というわけで、まずExcelで元データを作ります。
ここで、
・「中心座標」はマップの中心座標
・0〜10の番号の行が地図上のマーカの座標データとコメントのデータ
です。
この位置座標は、いつものように↓のような自作地図を作って、得た座標データをコピー&ペーストして作っています。
http://www7a.biglobe.ne.jp/~uso9000/hatena/ichi.htm
次に、元データに対して文字列連結演算子を使って、表右側のようにJSON形式に変換します。この時、オートフィル機能を使ってお手軽に行を増やしてデータを作って行きます。
変換後のJSON形式のデータが、↓です。
{ POINTS_NUM: 11,
cent_dat: [ { "x": "139.647219479084", "y": "35.4398667657344" } ],
point_dat: [
{ "x": "139.645733535289", "y": "35.4391325145282", "txt": "<table border=0><tr><td><img src='yokohama1_0s.jpg' /></td><td><div class='infowin'>名雪と商店街へ<br /><br /><a href='kanon-tv3-1.htm#txt0' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.647219479084", "y": "35.4398667657344", "txt": "<table border=0><tr><td><img src='yokohama1_1s.jpg' /></td><td><div class='infowin'>フードショップコスモス前<br /><br /><a href='kanon-tv3-1.htm#txt1' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.647772014141", "y": "35.4401399229561", "txt": "<table border=0><tr><td><img src='yokohama1_2s.jpg' /></td><td><div class='infowin'>商店街を見回す祐一<br /><br /><a href='kanon-tv3-1.htm#txt2' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.648139476776", "y": "35.4403081873434", "txt": "<table border=0><tr><td><img src='yokohama1_3s.jpg' /></td><td><div class='infowin'>あゆと逃走行<br /><br /><a href='kanon-tv3-1.htm#txt3' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.648909270763", "y": "35.4407102722471", "txt": "<table border=0><tr><td><img src='yokohama1_4s.jpg' /></td><td><div class='infowin'>百花屋に逃げ込む二人<br /><br /><a href='kanon-tv3-1.htm#txt4' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.648922681808", "y": "35.4406490855435", "txt": "<table border=0><tr><td><img src='yokohama1_5s.jpg' /></td><td><div class='infowin'>追って来たたい焼き屋さん<br /><br /><a href='kanon-tv3-1.htm#txt5' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.645671844482", "y": "35.4392854840817", "txt": "<table border=0><tr><td><img src='yokohama1_6s.jpg' /></td><td><div class='infowin'>たい焼き屋で謝る二人<br /><br /><a href='kanon-tv3-1.htm#txt6' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.646259248256", "y": "35.4393816362237", "txt": "<table border=0><tr><td><img src='yokohama1_7s.jpg' /></td><td><div class='infowin'>商店街に戻る二人<br /><br /><a href='kanon-tv3-1.htm#txt7' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.646382629871", "y": "35.4394428238907", "txt": "<table border=0><tr><td><img src='yokohama1_8s.jpg' /></td><td><div class='infowin'>商店街を歩く二人<br /><br /><a href='kanon-tv3-1.htm#txt8' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.64665621519", "y": "35.4395804959713", "txt": "<table border=0><tr><td><img src='yokohama1_9s.jpg' /></td><td><div class='infowin'>あゆとお別れ<br /><br /><a href='kanon-tv3-1.htm#txt9' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
{ "x": "139.6479088068", "y": "35.4401792575197", "txt": "<table border=0><tr><td><img src='yokohama1_10s.jpg' /></td><td><div class='infowin'>少年祐一と少女あゆが駆け出す<br /><br /><a href='kanon-tv3-1.htm#txt10' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" }
] }
これをExcelからコピー&ペーストで切り出してテキストファイルにし、FTPでWebサーバにアップします。
以上でデータ部の作成は完了です。
2.JavaScriptの作成
今回作成したJavaScriptを下記↓に示します。
※下記のJavaScriptは、商業利用以外の私的利用については、コピーおよび使用は自由にしていただいてかまいません。
※使用する場合、全角スペースは半角スペースに変換して下さい。
var map;
var markers = ;
var points = ;
var i;
var httpObj;
function startUp() {
map = new GMap2(document.getElementById("mymap"));
map.addControl(new GMapTypeControl());
map.addControl(new GLargeMapControl());
map.addControl(new GScaleControl());
var msec = (new Date()).getTime();
httpObj = GXmlHttp.create();
httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);
httpObj.onreadystatechange = function () {
if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
setMap();
}
}
httpObj.send(null);
}
function setMap() {
eval("var mapData = "+httpObj.responseText);
map.setCenter(new GLatLng(mapData.cent_dat[0].y, mapData.cent_dat[0].x), 17);
for (i = 0; i < mapData.POINTS_NUM; i++) {
points[i] = new GLatLng(mapData.point_dat[i].y, mapData.point_dat[i].x);
addMarker(points[i], i, mapData.point_dat[i].txt);
}
var polyline = new GPolyline(points, "#99FFFF", 3, 0.5);
map.addOverlay(polyline);
}
function addMarker(latlng, num, comment) {
var icon = new GIcon();
icon.image = "../markers/marker"+num+".png";
icon.iconSize = new GSize(20,34);
icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
icon.shadowSize = new GSize(37, 34);
icon.iconAnchor = new GPoint(10, 34);
icon.infoWindowAnchor = new GPoint(20, 10);
markers[num] = new GMarker(latlng, icon);
map.addOverlay(markers[num]);
var f = function() {
markers[num].openInfoWindowHtml(comment);
}
GEvent.addListener(markers[num], "click", f);
var marker_field = document.getElementById('mark'+ num);
var fzoom = function() {
f();
map.panTo(latlng);
map.setZoom(18);
}
marker_field.onmousedown = fzoom;
}
if (GBrowserIsCompatible()) {
onload=startUp;
onunload=GUnload;
}
詳しい説明をすると長くなるので、以下、ポイントを絞って解説します。
今回のポイントは、13行目からの下記の部分です。
var msec = (new Date()).getTime();
httpObj = GXmlHttp.create();
httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);
httpObj.onreadystatechange = function () {
if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
setMap();
}
}
httpObj.send(null);
この部分が実行されると、先にWebサーバ上にアップされたデータ部を、Googleのサーバが読み込みます。(そのため、このJavaScriptは、ローカルではデバッグ出来ないという副産物が付くのですが…)
読み込みに成功すると、
if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
setMap();
}
↑のif文の中の、setMap関数が実行されます。setMap関数中ではどうなるかというと、
eval("var mapData = "+httpObj.responseText);
map.setCenter(new GLatLng(mapData.cent_dat[0].y, mapData.cent_dat[0].x), 17);
1行目で変数mapDataにサーバが読みとったJSON形式のデータを代入し、
2行目でmapDataからマップの中心データを読み込んで、マップの中心座標をセットします。
次に、setMap関数中では、
for (i = 0; i < mapData.POINTS_NUM; i++) {
points[i] = new GLatLng(mapData.point_dat[i].y, mapData.point_dat[i].x);
addMarker(points[i], i, mapData.point_dat[i].txt);
}
mapData変数中のマーカの個数分だけループを繰り返して、マップ中にマーカをセットします。
最後のsetMap関数中の、
var polyline = new GPolyline(points, "#99FFFF", 3, 0.5);
map.addOverlay(polyline);
は、マーカ間にラインを引くための処理です。
以上のように、このJavaScriptは、マップが変わった時にでも15行目の↓の部分のファイル名だけを変更すれば良いようになっています。
httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);
3.HTML(XML)の作成
探訪記のメイン部分である、XMLファイルの記述は従来とほとんど変わっていません。
が、1点だけ、ヘッダに↓の記述を追記する必要があります。
<html xmlns="http://www3.org/199/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xml:lang="ja" lang="ja">
<style type="text/css">
v\:* {
behavior:url(#default#VML);
}
これは、Google Mapsが、Internet Explorerでマップ上のラインを引くためにVMLの機能を使う必要があるため、だそうです。
こうして出来たのが、↓の試作版というわけです。
京アニ「Kanon」横浜探訪記 第1話 試作版
以上、長文ですみませんでしたが、みなさんの舞台探訪記の参考になれば幸いです。