之前在地图上展示的园区模型增加了选中效果,但是对于展示性质的大屏而言,内容一直是静态展示的效果肯定不好。
所以模型自动环绕展示是绝对的核心亮点功能!无论是展厅大屏演示、项目汇报、还是产品展示,流畅的360°环绕浏览都能让你的三维场景瞬间提升质感。
简单整理了4种开箱即用的环绕方案,从极简入门到专业级平滑动画全覆盖,适配不同项目需求,复制代码直接运行!
flyToLocation + 定时器(极简)
利用之前封装 cesium-viewer 组件做的 flyToLocation 方法实现此功能。
之前封装的 flyToLocation 方法其实就是 cesium.camera.flyTo 方法。
这个方案代码最简单,无需复杂数学计算。支持分段式环绕,适合快速实现需求
可控制停留时间、飞行速度、环绕点数。
完整代码
// 环绕展示工厂模型
const displayFactoryModel = () => {
if (!cesiumViewRef.value) return;
const centerLon = 117.104273; // 模型中心点经度
const centerLat = 36.437867; // 模型中心点纬度
const radius = 150; // 环绕半径(米)
const height = 80; // 相机高度
const duration = 2; // 每个角度飞行时间(秒)
let currentAngle = 0;
const totalAngles = 8; // 环绕8个点
const angleStep = 360 / totalAngles;
const flyToNextPoint = () => {
// 计算当前角度的位置
const rad = currentAngle * Math.PI / 180;
const offsetX = radius * Math.cos(rad);
const offsetY = radius * Math.sin(rad);
// 计算新的经纬度(简化计算,适用于小范围)
const newLon = centerLon + (offsetX / 111320 / Math.cos(centerLat * Math.PI / 180));
const newLat = centerLat + (offsetY / 111320);
// 计算相机朝向(朝向中心点)
const heading = (currentAngle + 180) % 360;
cesiumViewRef.value.flyToLocation({
longitude: newLon,
latitude: newLat,
height: height,
duration: duration,
heading: heading,
pitch: -30, // 稍微俯视的角度
onComplete: () => {
currentAngle = (currentAngle + angleStep) % 360;
setTimeout(flyToNextPoint, 500); // 短暂停留后继续
}
});
};
flyToNextPoint();
};
lookAt + 帧动画(推荐)
这个方案相较于上面的方案比较好的一点就是真正的360°无缝平滑环绕。
这种方案无卡顿、无跳跃,动画效果最自然,并且支持无限循环环绕。生产环境推荐首选方案
完整代码
// 环绕展示工厂模型
const displayFactoryModel = () => {
if (!cesiumViewer.value) return;
const center = Cesium.Cartesian3.fromDegrees(117.104273, 36.437867, 0);
const radius = 150; // 环绕半径
const height = 80; // 相机高度
const duration = 20; // 完整环绕一周的时间(秒)
let startTime = null;
let animationId = null;
const animateOrbit = (timestamp) => {
if (!startTime) startTime = timestamp;
const elapsed = (timestamp - startTime) / 1000;
// 计算当前角度(0到2π)
const angle = (elapsed / duration) * 2 * Math.PI;
// 计算相机位置(圆形轨道)
const cameraX = center.x + radius * Math.cos(angle);
const cameraY = center.y + radius * Math.sin(angle);
const cameraZ = center.z + height;
const cameraPosition = new Cesium.Cartesian3(cameraX, cameraY, cameraZ);
// 设置相机位置和朝向(看向中心点)
cesiumViewer.value.camera.lookAt(
cameraPosition,
center, // 看向中心点
new Cesium.Cartesian3(0, 0, 1) // up方向
);
// 继续动画
animationId = requestAnimationFrame(animateOrbit);
};
// 开始动画
animationId = requestAnimationFrame(animateOrbit);
// 返回停止函数(可选)
return () => {
if (animationId) {
cancelAnimationFrame(animationId);
}
};
};
flyTo + 曲线路径
基于样条曲线生成平滑路径。支持自定义轨迹点、飞行总时长。
这个方案可以实现复杂环绕、俯冲、拉升等动作,但是如果不是动态模型运动没太大必要用这个。
完整代码
// 环绕展示工厂模型
const displayFactoryModel = () => {
if (!cesiumViewer.value) return;
const center = Cesium.Cartesian3.fromDegrees(117.104273, 36.437867, 0);
const radius = 150;
const height = 80;
const points = 12; // 路径点数
const duration = 30; // 总飞行时间
// 创建路径点
const positions = [];
for (let i = 0; i <= points; i++) {
const angle = (i / points) * 2 * Math.PI;
const x = center.x + radius * Math.cos(angle);
const y = center.y + radius * Math.sin(angle);
const z = center.z + height;
positions.push(new Cesium.Cartesian3(x, y, z));
}
// 相机沿路径飞行
cesiumViewer.value.camera.flyTo({
destination: positions,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-30),
roll: 0.0
},
duration: duration,
complete: () => {
console.log('✅ 环绕展示完成');
}
});
};
camera.rotate 旋转(极简)
这种方案代码量最少,一行核心逻辑。直接使用原地旋转视角,不改变相机位置。
但是展示效果一般,只能原地自转,不能环绕。
完整代码
// 环绕展示工厂模型
const displayFactoryModel = () => {
if (!cesiumViewer.value) return;
// 先飞到模型上方
cesiumViewRef.value.flyToLocation({
longitude: 117.104273,
latitude: 36.437867,
height: 80,
duration: 3,
heading: 0,
pitch: -30,
onComplete: () => {
// 开始旋转
let angle = 0;
const rotateInterval = setInterval(() => {
angle = (angle + 1) % 360;
cesiumViewer.value.camera.setView({
orientation: {
heading: Cesium.Math.toRadians(angle),
pitch: Cesium.Math.toRadians(-30),
roll: 0.0
}
});
}, 50); // 每50ms旋转1度
// 10秒后停止
setTimeout(() => {
clearInterval(rotateInterval);
console.log('✅ 旋转结束');
}, 10000);
}
});
};
总结
模型环绕展示是Cesium展示模型非常好的一种方案,尤其是做会议室大屏使用。
展示修效果还是相当不错的,如果没有特殊要求,可以考虑使用 lookAt+帧动画,这是综合体验最优的方案。
强烈建议大家使用此方案,流畅不卡顿,用户体验直接拉满!