03Cesium实现旋转功能

(1)相机绕点旋转

相机视点固定,相机位置移动,保持相同的距离绕该视点旋转,可用于对物体的360度浏览。

//使用useState更新isrotate,用于控制旋转启动与暂停
const [isrotate,setIsrotate] = useState(false)
  const rotateIntervalRef = useRef(null);
  function rotatecam(){
    var viewer = viewerRef.current
    if (isrotate) {
      clearInterval(rotateIntervalRef.current);
    } 
    else {
      var center = new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2);
      var cartesian = viewer.scene.camera.pickEllipsoid(center)
      if (cartesian) {
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude);
      }
      var position = Cesium.Cartesian3.fromDegrees(longitude,latitude,0);
      var pitch = viewer.camera.pitch
      var angle = 360 / 30;
      var distance = Cesium.Cartesian3.distance(cartesian,viewer.camera.position)
      var startTime = Cesium.JulianDate.fromDate(new Date());

      viewer.clock.startTime = startTime.clone();
      viewer.clock.currentTime = startTime.clone(); 
      viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; 
      viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; 
      // 相机的当前heading
      var initialHeading = viewer.camera.heading;
      rotateIntervalRef.current = setInterval(() => {
        var delTime = Cesium.JulianDate.secondsDifference(
          viewer.clock.currentTime,
          viewer.clock.startTime
        );
        var heading = initialHeading - Cesium.Math.toRadians(delTime * angle);
        viewer.scene.camera.setView({
          destination: position,
          orientation: {
            heading: heading,
            pitch: pitch,
          },
        });
        viewer.scene.camera.moveBackward(distance);
       }, 1000 / 30);     
    }
    setIsrotate(isrotate=>!isrotate)
  }

绕点旋转

(2)固定位置旋转(第一人称效果)

相机位置不动,镜头朝向改变,可用于浏览物体周围景观。

const [isrotate,setIsrotate] = useState(false)
    const rotateIntervalRef = useRef(null);
    function rotate(){
        var viewer = viewerRef.current
        if (isrotate) {
        clearInterval(rotateIntervalRef.current);
        } 
        else {
        var position = viewer.camera.position;
        var pitch = viewer.camera.pitch
        var angle = 360 / 30;
        var startTime = Cesium.JulianDate.fromDate(new Date());

        viewer.clock.startTime = startTime.clone();
        viewer.clock.currentTime = startTime.clone(); 
        viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; 
        viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; 
        // 相机的当前heading
        var initialHeading = viewer.camera.heading;
        rotateIntervalRef.current = setInterval(() => {
            var delTime = Cesium.JulianDate.secondsDifference(
            viewer.clock.currentTime,
            viewer.clock.startTime
            );
            var heading = initialHeading - Cesium.Math.toRadians(delTime * angle);
            viewer.scene.camera.setView({
            destination: position,
            orientation: {
                heading: heading,
                pitch: pitch,
            },
            });

        }, 1000 / 30);     
        }
        setIsrotate(isrotate=>!isrotate)
    }

视角自动旋转观察四周

若需要实现手动上下左右旋转浏览,核心代码如下:

function rotor(){
    var viewer = viewerRef.current
    var startPos;
    //取消视图的一些浏览功能
    viewer.scene.screenSpaceCameraController.enableRotate = false;  
    viewer.scene.screenSpaceCameraController.enableTranslate = false;  
    viewer.scene.screenSpaceCameraController.enableTilt = false;  
    let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(function(event) {
      startPos = new Cesium.Cartesian2(event.position.x,event.position.y)
    },Cesium.ScreenSpaceEventType.LEFT_DOWN)
    handler.setInputAction(function(event) {
      if(!startPos){
        return
      }
      var endPos = new Cesium.Cartesian2(event.endPosition.x,event.endPosition.y)
      var move = Cesium.Cartesian2.subtract(endPos,startPos,new Cesium.Cartesian2())
      var x_move = move.x;
      var y_move = move.y;

      viewer.camera.setView({
        destination:viewer.camera.position,
        orientation:{
          heading: viewer.camera.heading+Cesium.Math.toRadians(x_move),
          pitch: viewer.camera.pitch+Cesium.Math.toRadians(-y_move)
        }
      })
      startPos = endPos;
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    handler.setInputAction(function(event) {
      startPos = undefined
    },Cesium.ScreenSpaceEventType.LEFT_UP)
  }
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
在前端界面中实现Cesium鼠标旋转gltf模型需要以下步骤: 1. 导入Cesium库:首先需要在HTML文件中导入Cesium库,可以通过CDN链接或者本地文件引入,例如: ```html <script src="https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Cesium.js"></script> ``` 2. 创建Cesium Viewer:在JavaScript代码中创建一个Cesium Viewer对象,用于渲染模型和实现交互功能,例如: ```javascript var viewer = new Cesium.Viewer('cesiumContainer', { animation: false, timeline: false }); ``` 这里将模型渲染到ID为"cesiumContainer"的HTML元素中,设置animation和timeline为false,以禁用动画和时间轴显示。 3. 导入模型:使用Cesium提供的Entity对象来导入和显示gltf模型,例如: ```javascript var modelEntity = viewer.entities.add({ name: 'Model', position: Cesium.Cartesian3.fromDegrees(lon, lat, height), model: { uri: 'path/to/model.gltf' } }); ``` 这里通过设置模型的URI属性指定要加载的模型文件路径,并使用Cartesian3对象设置模型的初始位置。 4. 实现鼠标旋转功能:使用Cesium提供的默认交互功能或者自定义代码来实现鼠标旋转模型。例如,可以使用以下代码启用默认的鼠标交互: ```javascript viewer.screenSpaceEventHandler.setInputAction(function(event) { var feature = viewer.scene.pick(event.position); if (Cesium.defined(feature) && Cesium.defined(feature.id)) { modelEntity.rotation = Cesium.fromHeadingPitchRoll(new Cesium.HeadingPitchRoll(0, 0, 0)); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); ``` 这里使用screenSpaceEventHandler以左键单击为触发事件,通过判断拾取到的feature来设置模型的旋转,此处设置为0。 总结起来,实现Cesium鼠标旋转gltf模型的步骤包括导入Cesium库、创建Cesium Viewer、导入模型和实现鼠标旋转功能。以上只是一个简单的示例,根据实际需求和具体情况可能需要更加细致的操作和配置。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wfq0007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值