原生Cesium实现绕点飞行功能

功能实现:点击开始可实现在地图上绘制任意一点,并绕该点进行旋转,可通过el-slider控制旋转速度,点击停止按钮停止,并在点击开始后在刚刚停止位置继续旋转。

代码:

            <div class="header-context">绕点飞行</div>

 <button @click="startObserving">

            <span ><img src="@/assets/img/start.png" alt="" /></span>开始

            </button>

            <button @click="stopObserving"   <span><img src="@/assets/img/stop.png"

                        alt="" /></span>停止

            </button>

            <div>

                <el-slider class="input-range" v-model="rollNumber" :show-tooltip="false" :min="1" :max="100" />

            </div>

let distance;  // 相机与目标点的距离

let angle;  // 相机的旋转角度

let stopTime;  // 停止时间

let initialHeading;  // 初始朝向

let pitch;  // 相机的俯仰角

let startTime;  // 开始时间

let isRotating = false;  // 标记是否正在旋转

let position;  // 目标点位置

let entity;  // 绘制的实体

let lastCameraState = {};  // 上次相机的状态

const rollNumber = ref(20);  // 滚动速度

// 开始绕点飞行

const startObserving = () => {

    if (isRotating) {

        return;  // 如果已经在旋转,则返回

    }

    if (position) {

        // 如果已选择目标点,则开始绕点飞行

        initialHeading = window.viewer.scene.camera.heading;

        distance = Cesium.Cartesian3.distance(window.viewer.scene.camera.position, position);

        pitch = window.viewer.scene.camera.pitch;

        startTime = Cesium.JulianDate.fromDate(new Date());

        stopTime = Cesium.JulianDate.addSeconds(startTime, Number.POSITIVE_INFINITY, new Cesium.JulianDate());

        window.viewer.clock.startTime = startTime.clone();

        window.viewer.clock.stopTime = stopTime.clone();

        window.viewer.clock.currentTime = startTime.clone();

        window.viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;

        window.viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;

        window.viewer.clock.onTick.addEventListener(execution);

        isRotating = true;

    } else {

        // 如果未选择目标点,则添加事件处理器选择目标点

        let handler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);

        handler.setInputAction(function (click) {

            if (window.viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {

                return;

            }

            let cartesian = window.viewer.camera.pickEllipsoid(click.position);

            if (cartesian) {

                position = Cesium.Cartesian3.clone(cartesian);

                entity = window.viewer.entities.add({

                    position: position,

                    point: {

                        pixelSize: 10,

                        color: Cesium.Color.RED,

                        outlineColor: Cesium.Color.WHITE,

                        outlineWidth: 2,

                    },

                });

                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);

                initialHeading = window.viewer.scene.camera.heading;

                distance = Cesium.Cartesian3.distance(window.viewer.scene.camera.position, position);

                pitch = window.viewer.scene.camera.pitch;

                startTime = Cesium.JulianDate.fromDate(new Date());

                stopTime = Cesium.JulianDate.addSeconds(startTime, Number.POSITIVE_INFINITY, new Cesium.JulianDate());

                window.viewer.clock.startTime = startTime.clone();

                window.viewer.clock.stopTime = stopTime.clone();

                window.viewer.clock.currentTime = startTime.clone();

                window.viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;

                window.viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;

                window.viewer.clock.onTick.addEventListener(execution);

                isRotating = true;

            }

        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    }

};

// 在每个时钟滴答时执行

const execution = () => {

    var delTime = Cesium.JulianDate.secondsDifference(window.viewer.clock.currentTime, window.viewer.clock.startTime);

    // 计算当前的航向增量

    var headingIncrement = Cesium.Math.toRadians(delTime * rollNumber.value);

    // 防止出现因速度减慢而导致的逆时针旋转

    var heading = initialHeading + headingIncrement;

    window.viewer.scene.camera.setView({

        destination: position,

        orientation: {

            heading: heading,

            pitch: pitch,

        }

    });

    window.viewer.scene.camera.moveBackward(distance);

    if (Cesium.JulianDate.compare(window.viewer.clock.currentTime, window.viewer.clock.stopTime) >= 0) {

        window.viewer.clock.onTick.removeEventListener(execution);

        isRotating = false;

    }

};

// 监视 rollNumber 的变化

watch(rollNumber, (newVal, oldVal) => {

    if (isRotating) {

        // 记录当前航向和时间

        var currentTime = Cesium.JulianDate.now();

        var elapsed = Cesium.JulianDate.secondsDifference(currentTime, startTime);

        initialHeading += Cesium.Math.toRadians(elapsed * oldVal);

        startTime = currentTime;

        window.viewer.clock.startTime = startTime.clone();

        window.viewer.clock.currentTime = startTime.clone();

    }

});


 

// 停止绕点飞行

const stopObserving = () => {

    if (isRotating) {

        window.viewer.clock.onTick.removeEventListener(execution);

        isRotating = false;

        window.viewer.clock.currentTime = stopTime.clone();

        lastCameraState = {

            position: window.viewer.scene.camera.position.clone(),

            heading: window.viewer.scene.camera.heading,

            pitch: window.viewer.scene.camera.pitch

        };

    }

};

// 移除绘制的实体

const removeEntity = () => {

    if (entity) {

        window.viewer.entities.remove(entity);

        entity = null;

        position = null;

    }

};

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium是一个用于创建3D地球和地图JavaScript库。要在Cesium实现飞机飞行,你可以首先创建一个代表飞机的3D模型,并将其添加到Cesium场景中。然后,你可以使用Cesium的实体(Entity)和样条路径(Spline)功能来模拟飞行路径。 首先,你需要在Cesium中加载飞机的3D模型。你可以使用Cesium的3D模型加载器来加载模型文件,例如Gltf或Collada格式的文件。加载模型后,你可以将其添加到Cesium的场景(Scene)中。 接下来,你可以使用实体(Entity)来表示飞机。实体是Cesium中的一个概念,它代表场景中的一个可视对象。你可以为飞机创建一个实体,并设置其位置、方向和姿态等属性。通过更新实体的属性,你可以模拟飞机在场景中的移动和旋转。 为了实现飞行路径,你可以使用样条路径(Spline)功能Cesium提供了一个样条路径插值器(CatmullRomSpline)来生成平滑的飞行路径。你可以根据你想要的路径点的位置和时间信息,使用插值器来计算出飞机在每个时间点的位置。然后,通过设置实体的位置属性,让飞机沿着计算出的路径进行飞行。 最后,你可以使用Cesium的时间控制功能来控制飞行的速度和时间进度。通过调整时间的流逝速度,你可以模拟飞机的飞行速度。你还可以使用Cesium的摄像机控制功能来跟踪飞机,使其在飞行过程中始终保持在视野中心。 总结来说,要在Cesium实现飞机飞行,你需要加载飞机模型、创建实体表示飞机、使用样条路径生成飞行路径,并使用时间和摄像机控制功能来控制飞行过程。这样,你就可以在Cesium实现一个基本的飞机飞行效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值