コンテンツにスキップ

Position curve

Set entity position with curve animation

anime_pin_curve_combo.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Position curve</title>
    <meta property="og:description" content="Set entity position with curve animation" />
    <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>
        body {margin: 0; padding: 0;}
        html, body, div#mapray-container { height: 100%; }
    </style>
</head>

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

<script>
    class CosCurveWithTime extends mapray.animation.Curve
    {
        constructor( type, keyframes )
        {
            super();

            if ( type != mapray.animation.Type.find("number") ) {
                throw mapray.animation.AnimationError( "unsupported type" );
            }

            this._value_type = type;
            this._ratio = 1.0
            this._base_value = 1.0;
            this._value_ratio = 1.0
            this._start_time = 0;
            this._end_time = 10;
        }

        setRatio( ratio )
        {
            this._ratio = ratio;
        }

        setBaseValue( value )
        {
            this._base_value = value;
        }

        setValueRatio( ratio )
        {
            this._value_ratio = ratio;
        }

        setStartTime( time )
        {
            this._start_time = time;
        }

        setEndTime( time )
        {
            this._end_time = time;
        }

        /**
         * @override
         */
        isTypeSupported( type )
        {
            let from_type = this._value_type;
            return type.isConvertible( from_type );
        }


        /**
         * @override
         */
        getValue( time, type )
        {
            let from_type  = this._value_type;
            let from_value = this._getInterpolatedValue( time );
            return type.convertValue( from_type, from_value );
        }


        /**
         * @override
         */
        getInvariance( interval )
        {
            const first = mapray.animation.Time.fromNumber(this._start_time);
            const last = mapray.animation.Time.fromNumber(this._end_time);
            const ival_inner = new mapray.animation.Interval( first, last, true, true );

            const invariance = new mapray.animation.Invariance();
            invariance.write(ival_inner.getPrecedings());
            invariance.write(ival_inner.getFollowings());

            return invariance.getNarrowed( interval );
        }

        _getInterpolatedValue( time )
        {
            const theta = (time.toNumber() * this._ratio + 180) * mapray.GeoMath.DEGREE;
            return (Math.cos(theta) + 1) * 0.5 * this._value_ratio + this._base_value;
        }
    }

    class AnimationView extends maprayui.StandardUIViewer {
        constructor(container, apikey, options) {
            super(container, apikey, options);

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

            const point = new mapray.GeoPoint(139.699985, 35.690777, 20);
            this.AddPin(point);
        }

        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));
            }
        }

        AddPin(geo_point) {

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

            // ピンを追加
            pin_entity.addPin(geo_point, { id: 0, size: 40, bg_color: [1, 0, 0] });

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

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

            this.pin_entity = pin_entity.getEntry(0);

            // UpdaterにBindingBlockを紐づける
            this.pin_entity.animation.bind("position", this.updater, this.curve);

            this.is_animation_start = true;
        }

        // キーフレームデータの作成
        createCurve(closs_geoPoint) {

            this.curve = new mapray.animation.ComboVectorCurve(mapray.animation.Type.find("vector3"));
            this.curve1 = new mapray.animation.ConstantCurve(mapray.animation.Type.find("number"));
            this.curve2 = new mapray.animation.ConstantCurve(mapray.animation.Type.find("number"));
            this.curve3 = new CosCurveWithTime(mapray.animation.Type.find("number"));

            // キーフレームデータの作成
            this.curve1.setConstantValue(closs_geoPoint.longitude);

            this.curve2.setConstantValue(closs_geoPoint.latitude);

            this.curve3.setRatio(45);
            this.curve3.setBaseValue(closs_geoPoint.altitude);
            this.curve3.setValueRatio(200.0);
            this.curve3.setStartTime(0);
            this.curve3.setEndTime(30);

            this.curve.setChildren([this.curve1,this.curve2,this.curve3]);

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

    // Set up your access token, which can be created in Mapray Cloud.
    var apikey= "<YOUR_MAPRAY_API_KEY>";

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

    var lookat_position = new mapray.GeoPoint(139.69685, 35.689777, 100.0);
    var mlocs_to_gocs = lookat_position.getMlocsToGocsMatrix( mapray.GeoMath.createMatrix() );
    var cam_pos = mapray.GeoMath.createVector3([0, -2000, 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_API_KEY>を、あなたのMapray CloudアカウントのAPI Keyに置き換えるまで、期待通りに動作しません。