コンテンツにスキップ

Custom animation

Custom animation with EasyBindingBlock

anime_path_easy_binding.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Custom animation</title>
    <meta property="og:description" content="Custom animation with EasyBindingBlock" />
    <script src="./v0.10.1/mapray.min.js"></script>
    <script src="./v0.10.1/maprayui.min.js"></script>
    <link rel="stylesheet" href="./v0.10.1/mapray.css">
    <style>
        body {margin: 0; padding: 0;}
        html, body, div#mapray-container { height: 100%; }
    </style>
</head>

<body>
<div id="mapray-container"></div>
</body>
</html>

<script>
    class AnimationView extends maprayui.StandardUIViewer {
        constructor( container, cloudApi ) {
            super( container, {
                dem_provider: new mapray.StandardDemProvider( cloudApi.getDefaultDemAsResource() )
            });

            this.is_animation_start = false;
            this.block = new mapray.animation.EasyBindingBlock();
            this.updater = new mapray.animation.Updater();
            this.total_time = 0;

            // エンティティの作成
            this.createText();
            this.createPin();
            this.createPath();

            // BindingBlockの作成
            this.createBlock();

            // キーフレームデータの作成
            this.createCurve();
        }

        onUpdateFrame(delta_time) {
            super.onUpdateFrame(delta_time);
            if (this.is_animation_start) {
                // 経過時間の更新
                this.total_time += delta_time;

                // Updaterに時間を投げる
                this.updater.update(mapray.animation.Time.fromNumber(this.total_time));
            }
        }

        // エンティティの作成
        createText() {
            // 文字のエンティティを作成
            var entity = new mapray.TextEntity(this.viewer.scene);

            // 仮の位置
            var font_point = new mapray.GeoPoint(0, 0, 0);

            entity.addText("0", font_point, { id: 0, color: [1, 1, 0], font_size: 50 });

            // エンティティをシーンに追加
            this.viewer.scene.addEntity(entity);
            this.text_entity = entity.getEntry(0);
        }

        // エンティティの作成
        createPin() {
            // ピンのエンティティを作成
            var entity = new mapray.PinEntity(this.viewer.scene);

            // 仮の位置
            var point = new mapray.GeoPoint(0, 0, 0);

            // ピンを追加
            entity.addPin(point, { id: 0, size: 50, bg_color: [0.5, 1, 1], fg_color: [0, 0, 0] });

            // エンティティをシーンに追加
            this.viewer.scene.addEntity(entity);
            this.pin_entity = entity.getEntry(0);
        }

        // エンティティの作成
        createPath() {
            // エンティティを作成
            var entity = new mapray.PathEntity(this.viewer.scene);
            entity.altitude_mode = mapray.AltitudeMode.CLAMP;
            // entity.altitude_mode = mapray.AltitudeMode.RELATIVE;

            var pos1 = [130.875921, 33.886291, 50.0];
            var pos2 = [130.873921, 33.884291, 50.0];
            var pos3 = [130.873921, 33.882291, 50.0];
            var pos4 = [130.874921, 33.881291, 50.0];

            var length = [0, 10, 20, 30];

            var pos_array = pos1;
            var length_array = [length[0]];

            var all_pos = pos1.concat(pos2).concat(pos3).concat(pos4);

            for (let i = 0; i < all_pos.length - 3; i = i + 3) {
                for (let j = 1; j <= 100; ++j) {
                    var dis = [
                        all_pos[i    ] + (all_pos[i + 3] - all_pos[i    ]) / 100 * j,
                        all_pos[i + 1] + (all_pos[i + 4] - all_pos[i + 1]) / 100 * j,
                        all_pos[i + 2] + (all_pos[i + 5] - all_pos[i + 2]) / 100 * j
                    ];

                    pos_array = pos_array.concat(dis);
                    length_array = length_array.concat(length[i / 3] + j / 10);
                }
            }

            this.position_array = pos_array;

            entity.addPoints(all_pos, length);
            entity.setLineWidth(5);
            entity.setColor(mapray.GeoMath.createVector3([1.0, 0.0, 0.0]));
            entity.setUpperLength(30);

            // エンティティをシーンに追加
            this.viewer.scene.addEntity(entity);
            this.path_entity = entity;
        }

        // EasyBindingBlockにアニメーション可能パラメータを追加
        createBlock() {
            const number = mapray.animation.Type.find( "number" );

            this.block.addEntry( "length", [number], null, value => {
                const position_value = Math.floor(value*10);
                if(this.position_array.length > position_value*3) {
                    const text_value = Math.floor(value);
                    this.text_entity.setText(text_value);
                    var altitude = this.viewer.getElevation(this.position_array[position_value*3+1], this.position_array[position_value*3+0]);
                    const text_position = new mapray.GeoPoint(this.position_array[position_value*3+0], this.position_array[position_value*3+1], altitude + 120);
                    this.text_entity.setPosition(text_position);
                    const pin_position = new mapray.GeoPoint(this.position_array[position_value*3+0], this.position_array[position_value*3+1], altitude);
                    this.pin_entity.setPosition(pin_position);
                }
                this.path_entity.setUpperLength(value);
            } );
        }

        // キーフレームデータの作成
        createCurve() {
            var marker_line = this.viewer.scene.getEntity(0);

            let keyframes = [];

            this.curve = new mapray.animation.KFLinearCurve(mapray.animation.Type.find("number"));

            // キーフレームデータの作成
            keyframes.push(mapray.animation.Time.fromNumber(0));
            keyframes.push(0);
            keyframes.push(mapray.animation.Time.fromNumber(30));
            keyframes.push(30);
            this.curve.setKeyFrames(keyframes);

            // 経過時間の初期化
            this.total_time = 0;

            // UpdaterにBindingBlockを紐づける
            this.block.bind("length", this.updater, this.curve);

            // アニメーションを開始
            this.is_animation_start = true;
        }
    }

    // Set up your access token, which can be created in Mapray Cloud.

    const cloudApi = new mapray.cloud.CloudApiV2({
        tokenType: mapray.cloud.CloudApi.TokenType.ACCESS_TOKEN,
        token: "<YOUR_MAPRAY_ACCESS_TOKEN>"
    });


    // The StandardUIView in the ui package includes mouse-based camera manipulation.
    var uiviewer = new AnimationView( "mapray-container", cloudApi );

    var lookat_position = new mapray.GeoPoint(130.873921, 33.884291, 3.0);
    var mlocs_to_gocs = lookat_position.getMlocsToGocsMatrix( mapray.GeoMath.createMatrix() );
    var cam_pos = mapray.GeoMath.createVector3([1000, 1000, 500]);
    var cam_pos_gocs = mapray.GeoMath.transformPosition_A(mlocs_to_gocs, cam_pos, mapray.GeoMath.createVector3() );
    var cam_pos_iscs = {longitude: 0, latitude:0, height:0};
    mapray.GeoMath.gocs_to_iscs(cam_pos_gocs, cam_pos_iscs);

    uiviewer.setCameraPosition({
        longitude: cam_pos_iscs.longitude,
        latitude: cam_pos_iscs.latitude,
        height: cam_pos_iscs.height
    });

    uiviewer.setLookAtPosition({
        longitude: lookat_position.longitude,
        latitude:  lookat_position.latitude,
        height: lookat_position.height
    });

</script>

Info

このサンプルコードは、<YOUR_MAPRAY_ACCESS_TOKEN>を、あなたのMapray CloudアカウントのOrganization Tokenに置き換えるまで、期待通りに動作しません。