3D火星视角
This commit is contained in:
108
src/App.vue
108
src/App.vue
@@ -1,71 +1,11 @@
|
||||
<template>
|
||||
<div ref="cesiumContainer" id="cesium-container"></div>
|
||||
<RouterView />
|
||||
<nav class="page-nav">
|
||||
<RouterLink to="/" class="nav-link">Earth</RouterLink>
|
||||
<RouterLink to="/mars" class="nav-link">Mars</RouterLink>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import * as Cesium from 'cesium'
|
||||
import 'cesium/Build/Cesium/Widgets/widgets.css'
|
||||
|
||||
// 替换为你自己的 token:https://ion.cesium.com
|
||||
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1ZGQ4MTNmMy01YTMwLTQ3MzYtOWYwOS0yNWJjY2M4NGMwZDkiLCJpZCI6MzkyNzAxLCJpYXQiOjE3NzE2Njg3NjV9.Ocngj9fTNpIJVIOD8__NGQd5o5blbBKJ-pl9Xzf-Cd4'
|
||||
|
||||
const cesiumContainer = ref(null)
|
||||
let viewer = null
|
||||
|
||||
onMounted(() => {
|
||||
viewer = new Cesium.Viewer(cesiumContainer.value, {
|
||||
terrain: Cesium.Terrain.fromWorldTerrain(),
|
||||
baseLayerPicker: false,
|
||||
geocoder: false,
|
||||
homeButton: false,
|
||||
sceneModePicker: false,
|
||||
navigationHelpButton: false,
|
||||
animation: false,
|
||||
timeline: false,
|
||||
fullscreenButton: false,
|
||||
})
|
||||
|
||||
// 移除默认 Bing Maps 底图,换成自己的全球图层
|
||||
viewer.imageryLayers.remove(viewer.imageryLayers.get(0))
|
||||
|
||||
// 第一层:Natural Earth 全球底图(port 8001)
|
||||
viewer.imageryLayers.addImageryProvider(
|
||||
new Cesium.UrlTemplateImageryProvider({
|
||||
url: 'http://localhost:8010/tiles/{z}/{x}/{y}.png',
|
||||
tilingScheme: new Cesium.WebMercatorTilingScheme(),
|
||||
maximumLevel: 15,
|
||||
credit: 'Natural Earth - HYP_HR_SR_OB_DR',
|
||||
})
|
||||
)
|
||||
|
||||
// // 第二层:NJ 高分辨率航拍(port 8000),叠加在全球底图之上
|
||||
// viewer.imageryLayers.addImageryProvider(
|
||||
// new Cesium.UrlTemplateImageryProvider({
|
||||
// url: 'http://localhost:8000/tiles/{z}/{x}/{y}.png',
|
||||
// tilingScheme: new Cesium.WebMercatorTilingScheme(),
|
||||
// maximumLevel: 21,
|
||||
// credit: 'NJ Open Imagery 2020 - I7D16',
|
||||
// })
|
||||
// )
|
||||
|
||||
// 从全球视角出发,飞向 NJ 影像区域
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(-74.30054, 40.61087, 12000000),
|
||||
// complete: () => {
|
||||
// viewer.camera.flyTo({
|
||||
// destination: Cesium.Cartesian3.fromDegrees(-74.30054, 40.61087, 3000),
|
||||
// duration: 3,
|
||||
// })
|
||||
// },
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
viewer?.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@@ -80,8 +20,40 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cesium-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
.page-nav {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 6px 10px;
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
font-family: sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
padding: 4px 14px;
|
||||
border-radius: 14px;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.nav-link.router-link-active {
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import * as Cesium from 'cesium'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1ZGQ4MTNmMy01YTMwLTQ3MzYtOWYwOS0yNWJjY2M4NGMwZDkiLCJpZCI6MzkyNzAxLCJpYXQiOjE3NzE2Njg3NjV9.Ocngj9fTNpIJVIOD8__NGQd5o5blbBKJ-pl9Xzf-Cd4'
|
||||
|
||||
createApp(App).use(router).mount('#app')
|
||||
|
||||
13
src/router/index.js
Normal file
13
src/router/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import EarthView from '../views/EarthView.vue'
|
||||
import MarsView from '../views/MarsView.vue'
|
||||
|
||||
const routes = [
|
||||
{ path: '/', component: EarthView },
|
||||
{ path: '/mars', component: MarsView },
|
||||
]
|
||||
|
||||
export default createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes,
|
||||
})
|
||||
51
src/views/EarthView.vue
Normal file
51
src/views/EarthView.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div ref="cesiumContainer" class="cesium-fullscreen"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import * as Cesium from 'cesium'
|
||||
import 'cesium/Build/Cesium/Widgets/widgets.css'
|
||||
|
||||
const cesiumContainer = ref(null)
|
||||
let viewer = null
|
||||
|
||||
onMounted(() => {
|
||||
viewer = new Cesium.Viewer(cesiumContainer.value, {
|
||||
terrain: Cesium.Terrain.fromWorldTerrain(),
|
||||
baseLayerPicker: false,
|
||||
geocoder: false,
|
||||
homeButton: false,
|
||||
sceneModePicker: false,
|
||||
navigationHelpButton: false,
|
||||
animation: false,
|
||||
timeline: false,
|
||||
fullscreenButton: false,
|
||||
})
|
||||
|
||||
viewer.imageryLayers.remove(viewer.imageryLayers.get(0))
|
||||
viewer.imageryLayers.addImageryProvider(
|
||||
new Cesium.UrlTemplateImageryProvider({
|
||||
url: 'http://localhost:8010/tiles/{z}/{x}/{y}.png',
|
||||
tilingScheme: new Cesium.WebMercatorTilingScheme(),
|
||||
maximumLevel: 15,
|
||||
credit: 'Natural Earth - HYP_HR_SR_OB_DR',
|
||||
})
|
||||
)
|
||||
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(-74.30054, 40.61087, 12000000),
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
viewer?.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cesium-fullscreen {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
63
src/views/MarsView.vue
Normal file
63
src/views/MarsView.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div ref="cesiumContainer" class="cesium-fullscreen"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import * as Cesium from 'cesium'
|
||||
import 'cesium/Build/Cesium/Widgets/widgets.css'
|
||||
|
||||
const cesiumContainer = ref(null)
|
||||
let viewer = null
|
||||
|
||||
onMounted(async () => {
|
||||
viewer = new Cesium.Viewer(cesiumContainer.value, {
|
||||
terrainProvider: false,
|
||||
baseLayer: false,
|
||||
baseLayerPicker: false,
|
||||
geocoder: false,
|
||||
homeButton: false,
|
||||
sceneModePicker: false,
|
||||
navigationHelpButton: false,
|
||||
animation: false,
|
||||
timeline: false,
|
||||
fullscreenButton: false,
|
||||
shadows: false,
|
||||
globe: new Cesium.Globe(Cesium.Ellipsoid.MARS),
|
||||
skyBox: Cesium.SkyBox.createEarthSkyBox(),
|
||||
skyAtmosphere: new Cesium.SkyAtmosphere(Cesium.Ellipsoid.MARS),
|
||||
})
|
||||
|
||||
// Hide the default globe mesh — surface comes from the Ion tileset
|
||||
viewer.scene.globe.show = false
|
||||
|
||||
// Mars-like atmosphere (reddish, thinner than Earth)
|
||||
const atmo = viewer.scene.skyAtmosphere
|
||||
atmo.atmosphereMieCoefficient = new Cesium.Cartesian3(9.0e-5, 2.0e-5, 1.0e-5)
|
||||
atmo.atmosphereRayleighCoefficient = new Cesium.Cartesian3(9.0e-6, 2.0e-6, 1.0e-6)
|
||||
atmo.atmosphereRayleighScaleHeight = 9000
|
||||
atmo.atmosphereMieScaleHeight = 2700.0
|
||||
atmo.saturationShift = -0.1
|
||||
atmo.perFragmentAtmosphere = true
|
||||
|
||||
// Mars global 3D tileset from Cesium Ion (asset 3644333)
|
||||
try {
|
||||
const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(3644333)
|
||||
viewer.scene.primitives.add(tileset)
|
||||
viewer.zoomTo(tileset)
|
||||
} catch (error) {
|
||||
console.error('Failed to load Mars tileset:', error)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
viewer?.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cesium-fullscreen {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user