Animation
Mapray JS でアニメーション表現する方法を説明します。
Note
- このページでは、最も簡単なアニメーション表現の実装方法を説明します。
- より詳細な説明は こちらのページ をご覧下さい。
アニメーションは、 Entity などの位置やサイズ、色などといったプロパティをフレーム毎に少しずつ変化させることで滑らかに動いているように見せるといった方法で実現されます。
ここでは、StandardUIViewer を継承して PinEntity のサイズをスムーズに変化させるプログラムを作成します。
Updater
Mapray JS では Updater を利用してアニメーション表現を実現します。
下記に実装方法の流れを示します。
Updater を初期化
- 時刻 \(t\) が更新されたことを
Updater に通知
- 時刻 \(t\) におけるプロパティの値 \(v\) の計算
- 値 \(v\) をプロパティに適用
基本的に、2は毎フレーム実行する必要がありますが、 1, 3, 4 については、最初に一度記述しておくことで自動的に毎フレーム処理されるようになっています。
まずは 「1. Updater を初期化」し、「2. 時刻 \(t\) が更新されたことを Updater に通知」するようにします。
1
2
3
4
5
6
7
8
9
10
11
12
13 | class CustomViewer extends maprayui.StandardUIViewer {
constructor( container, apikey ) {
super( container, apikey );
this.totalTime = 0;
this.updater = new mapray.animation.Updater();
}
onUpdateFrame( delta_time ) { // override
super.onUpdateFrame( delta_time );
this.totalTime += delta_time;
this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
}
}
|
Curve
「3. 時刻 \(t\) におけるプロパティの値 \(v\) を計算」するには、mapray.animation.Curve クラス(以降 Curve)を利用します。
Curve クラスにはいくつかの種類があり、状況に応じて適切な Curve を利用します。
今回は、キーフレームを指定して生成することができる KFLinearCurve を利用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | class CustomViewer extends maprayui.StandardUIViewer {
constructor( container, apikey ) {
super( container, apikey);
this.totalTime = 0;
this.updater = new mapray.animation.Updater();
const numberType = mapray.animation.Type.find( "number" );
const curve = new mapray.animation.KFLinearCurve( numberType );
curve.setKeyFrames([
mapray.animation.Time.fromNumber( 0 ), 5.0,
mapray.animation.Time.fromNumber( 5 ), 40.0,
]);
}
onUpdateFrame( delta_time ) { // override
super.onUpdateFrame( delta_time );
this.totalTime += delta_time;
this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
}
}
|
時刻 \(0[s]\) 時点で \(5.0\) 、時刻 \(5[s]\) で \(40.0\) としてキーフレームを設定します。
Bind
「4. 値 \(v\) をプロパティに適用」するには Updater と Curve をBindすることで実現します。
Bind の方法は通常の方法と簡易的な方法の2種類あります。
PinEntity の位置やサイズ、 PolygonEntity の色など、よく利用されるプロパティについては、簡易的に Bind する手段が用意されています。
今回はこの簡易的な方法を利用します。
簡易的な方法を利用できるかどうかはエンティティのリファレンスをご確認ください(例)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | class CustomViewer extends maprayui.StandardUIViewer {
constructor( container, apikey ) {
super( container, apikey);
this.totalTime = 0;
this.updater = new mapray.animation.Updater();
const numberType = mapray.animation.Type.find( "number" );
const curve = new mapray.animation.KFLinearCurve( numberType );
curve.setKeyFrames([
mapray.animation.Time.fromNumber( 0 ), 5.0,
mapray.animation.Time.fromNumber( 5 ), 40.0,
]);
// Create Entity
const pinEntity = new mapray.PinEntity( this.viewer.scene );
const pinEntry = pinEntity.addPin( new mapray.GeoPoint( 139.699985, 35.690777, 40 ));
this.viewer.scene.addEntity( pinEntity );
// Bind size param with the updater and curve
pinEntry.animation.bind( "size", this.updater, curve );
}
onUpdateFrame( delta_time ) { // override
super.onUpdateFrame( delta_time );
this.totalTime += delta_time;
this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
}
}
|
PinEntity 及びその Entry を定義し、 Entry の size プロパティに、 updater と curve をBindしています。
以上より、アニメーションフレーム毎に、時刻 \(t\) が更新され、 curve に従ってプロパティ値が計算され、計算結果が PinEntity (Entry) の size に設定されるようになります。
完全なサンプルコード
上記の完全なサンプルコードです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 | <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://resource.mapray.com/mapray-js/v0.9.6/mapray.min.js"></script>
<script src="https://resource.mapray.com/ui/v0.9.6/maprayui.min.js"></script>
<link rel="stylesheet" href="https://resource.mapray.com/styles/v1/mapray.css">
<style>
html, body, div#mapray-container { margin: 0; padding: 0; height: 100%; }
</style>
</head>
<body>
<div id="mapray-container"></div>
</body>
</html>
<script>
class CustomViewer extends maprayui.StandardUIViewer {
constructor( container, apikey ) {
super( container, apikey);
this.totalTime = 0;
this.updater = new mapray.animation.Updater();
// Create curve
const numberType = mapray.animation.Type.find( "number" );
const curve = new mapray.animation.KFLinearCurve( numberType );
curve.setKeyFrames([
mapray.animation.Time.fromNumber( 0 ), 5.0,
mapray.animation.Time.fromNumber( 5 ), 40.0,
]);
// Create Entity
const pinEntity = new mapray.PinEntity( this.viewer.scene );
const pinEntry = pinEntity.addPin( new mapray.GeoPoint( 139.699985, 35.690777, 40 ));
this.viewer.scene.addEntity( pinEntity );
// Bind size param with the updater and curve
pinEntry.animation.bind( "size", this.updater, curve );
}
onUpdateFrame( delta_time ) { // override
super.onUpdateFrame( delta_time );
this.totalTime += delta_time;
this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
}
}
// Set up your API Key, which can be created in Mapray Cloud.
const apikey = "<YOUR_MAPRAY_API_KEY>";
const uiviewer = new CustomViewer( "mapray-container", apikey);
uiviewer.setCameraPosition({
longitude: 139.697475,
latitude: 35.682494,
height: 420
});
uiviewer.setLookAtPosition({
longitude: 139.699985,
latitude: 35.690777,
height: 35
});
</script>
|