初始化
This commit is contained in:
12
index.html
Normal file
12
index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Cesium Vue3 项目</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1917
package-lock.json
generated
Normal file
1917
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
package.json
Normal file
30
package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "cesium-vue3-project",
|
||||
"version": "1.0.0",
|
||||
"description": "A Vue3 project integrated with Cesium for 3D geospatial visualization",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.0",
|
||||
"cesium": "^1.111.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.5.0",
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-cesium": "^1.2.22"
|
||||
},
|
||||
"keywords": [
|
||||
"vue3",
|
||||
"cesium",
|
||||
"3d",
|
||||
"geospatial",
|
||||
"visualization"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
||||
1047
src/App.vue
Normal file
1047
src/App.vue
Normal file
File diff suppressed because it is too large
Load Diff
247
src/cameraController.js
Normal file
247
src/cameraController.js
Normal file
@@ -0,0 +1,247 @@
|
||||
import * as Cesium from 'cesium'
|
||||
|
||||
/**
|
||||
* Cesium相机控制器类
|
||||
* 支持WASD键控制相机的上下左右移动
|
||||
* 支持灵敏度调节(0.2-2.5)
|
||||
*/
|
||||
class CameraController {
|
||||
constructor(viewer, options = {}) {
|
||||
this.viewer = viewer
|
||||
this.camera = viewer.camera
|
||||
this.scene = viewer.scene
|
||||
|
||||
// 默认配置
|
||||
this.config = {
|
||||
sensitivity: options.sensitivity || 0.005, // 灵敏度,范围0.001-0.1
|
||||
moveSpeed: options.moveSpeed || 100, // 基础移动速度
|
||||
enabled: options.enabled !== false, // 是否启用控制器
|
||||
...options
|
||||
}
|
||||
|
||||
// 按键状态
|
||||
this.keys = {
|
||||
w: false, // 向上
|
||||
s: false, // 向下
|
||||
a: false, // 向左
|
||||
d: false // 向右
|
||||
}
|
||||
|
||||
// 动画帧ID
|
||||
this.animationFrameId = null
|
||||
|
||||
// 绑定事件处理函数
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this)
|
||||
this.handleKeyUp = this.handleKeyUp.bind(this)
|
||||
this.updateCamera = this.updateCamera.bind(this)
|
||||
|
||||
// 初始化
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控制器
|
||||
*/
|
||||
init() {
|
||||
if (this.config.enabled) {
|
||||
this.enable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用相机控制
|
||||
*/
|
||||
enable() {
|
||||
this.config.enabled = true
|
||||
document.addEventListener('keydown', this.handleKeyDown)
|
||||
document.addEventListener('keyup', this.handleKeyUp)
|
||||
this.startAnimation()
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用相机控制
|
||||
*/
|
||||
disable() {
|
||||
this.config.enabled = false
|
||||
document.removeEventListener('keydown', this.handleKeyDown)
|
||||
document.removeEventListener('keyup', this.handleKeyUp)
|
||||
this.stopAnimation()
|
||||
// 重置按键状态
|
||||
this.keys = { w: false, s: false, a: false, d: false }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置灵敏度
|
||||
* @param {number} sensitivity - 灵敏度值,范围0.001-0.1
|
||||
*/
|
||||
setSensitivity(sensitivity) {
|
||||
this.config.sensitivity = Math.max(0.001, Math.min(0.1, sensitivity))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前灵敏度
|
||||
* @returns {number} 当前灵敏度值
|
||||
*/
|
||||
getSensitivity() {
|
||||
return this.config.sensitivity
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置移动速度
|
||||
* @param {number} speed - 基础移动速度
|
||||
*/
|
||||
setMoveSpeed(speed) {
|
||||
this.config.moveSpeed = Math.max(1, speed)
|
||||
}
|
||||
|
||||
/**
|
||||
* 键盘按下事件处理
|
||||
* @param {KeyboardEvent} event - 键盘事件
|
||||
*/
|
||||
handleKeyDown(event) {
|
||||
if (!this.config.enabled) return
|
||||
|
||||
const key = event.key.toLowerCase()
|
||||
if (key in this.keys) {
|
||||
this.keys[key] = true
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 键盘释放事件处理
|
||||
* @param {KeyboardEvent} event - 键盘事件
|
||||
*/
|
||||
handleKeyUp(event) {
|
||||
if (!this.config.enabled) return
|
||||
|
||||
const key = event.key.toLowerCase()
|
||||
if (key in this.keys) {
|
||||
this.keys[key] = false
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始动画循环
|
||||
*/
|
||||
startAnimation() {
|
||||
if (this.animationFrameId) {
|
||||
cancelAnimationFrame(this.animationFrameId)
|
||||
}
|
||||
this.updateCamera()
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止动画循环
|
||||
*/
|
||||
stopAnimation() {
|
||||
if (this.animationFrameId) {
|
||||
cancelAnimationFrame(this.animationFrameId)
|
||||
this.animationFrameId = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新相机位置
|
||||
*/
|
||||
updateCamera() {
|
||||
if (!this.config.enabled) return
|
||||
|
||||
// 检查是否有按键被按下
|
||||
const hasMovement = Object.values(this.keys).some(pressed => pressed)
|
||||
|
||||
if (hasMovement) {
|
||||
// 获取相机的当前方向向量
|
||||
const camera = this.camera
|
||||
const right = camera.right.clone()
|
||||
const up = camera.up.clone()
|
||||
|
||||
// 计算移动向量
|
||||
let moveVector = new Cesium.Cartesian3(0, 0, 0)
|
||||
|
||||
// 上下移动 (W/S)
|
||||
if (this.keys.w) {
|
||||
moveVector = Cesium.Cartesian3.add(moveVector, up, moveVector)
|
||||
}
|
||||
if (this.keys.s) {
|
||||
const down = Cesium.Cartesian3.negate(up, new Cesium.Cartesian3())
|
||||
moveVector = Cesium.Cartesian3.add(moveVector, down, moveVector)
|
||||
}
|
||||
|
||||
// 左右移动 (A/D)
|
||||
if (this.keys.a) {
|
||||
const left = Cesium.Cartesian3.negate(right, new Cesium.Cartesian3())
|
||||
moveVector = Cesium.Cartesian3.add(moveVector, left, moveVector)
|
||||
}
|
||||
if (this.keys.d) {
|
||||
moveVector = Cesium.Cartesian3.add(moveVector, right, moveVector)
|
||||
}
|
||||
|
||||
// 标准化移动向量
|
||||
if (Cesium.Cartesian3.magnitude(moveVector) > 0) {
|
||||
moveVector = Cesium.Cartesian3.normalize(moveVector, moveVector)
|
||||
|
||||
// 应用灵敏度和移动速度
|
||||
const moveDistance = this.config.moveSpeed * this.config.sensitivity
|
||||
moveVector = Cesium.Cartesian3.multiplyByScalar(moveVector, moveDistance, moveVector)
|
||||
|
||||
// 移动相机
|
||||
camera.move(moveVector, moveDistance)
|
||||
}
|
||||
}
|
||||
|
||||
// 继续动画循环
|
||||
this.animationFrameId = requestAnimationFrame(this.updateCamera)
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁控制器
|
||||
*/
|
||||
destroy() {
|
||||
this.disable()
|
||||
this.viewer = null
|
||||
this.camera = null
|
||||
this.scene = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前配置
|
||||
* @returns {Object} 当前配置对象
|
||||
*/
|
||||
getConfig() {
|
||||
return { ...this.config }
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
* @param {Object} newConfig - 新的配置选项
|
||||
*/
|
||||
updateConfig(newConfig) {
|
||||
this.config = { ...this.config, ...newConfig }
|
||||
|
||||
// 如果灵敏度超出范围,自动调整
|
||||
if (this.config.sensitivity < 0.001) {
|
||||
this.config.sensitivity = 0.001
|
||||
} else if (this.config.sensitivity > 0.1) {
|
||||
this.config.sensitivity = 0.1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置所有按键状态
|
||||
*/
|
||||
resetKeys() {
|
||||
this.keys = { w: false, s: false, a: false, d: false }
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否正在移动
|
||||
* @returns {boolean} 是否有按键被按下
|
||||
*/
|
||||
isMoving() {
|
||||
return Object.values(this.keys).some(pressed => pressed)
|
||||
}
|
||||
}
|
||||
|
||||
export default CameraController
|
||||
9
src/main.js
Normal file
9
src/main.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import './style.css'
|
||||
|
||||
// 创建Vue应用实例
|
||||
const app = createApp(App)
|
||||
|
||||
// 挂载应用
|
||||
app.mount('#app')
|
||||
81
src/style.css
Normal file
81
src/style.css
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 全局样式重置 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #1a1a1a;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Cesium容器样式 */
|
||||
.cesium-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 工具栏样式 */
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
z-index: 1000;
|
||||
background: rgba(42, 42, 42, 0.8);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.toolbar button {
|
||||
background: #48b884;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
margin: 0 5px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.toolbar button:hover {
|
||||
background: #369870;
|
||||
}
|
||||
|
||||
/* 信息面板样式 */
|
||||
.info-panel {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 1000;
|
||||
background: rgba(42, 42, 42, 0.9);
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(10px);
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.info-panel h3 {
|
||||
margin-bottom: 10px;
|
||||
color: #48b884;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.info-panel p {
|
||||
margin: 5px 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
28
vite.config.js
Normal file
28
vite.config.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import cesium from 'vite-plugin-cesium'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
cesium()
|
||||
],
|
||||
server: {
|
||||
port: 3001,
|
||||
open: true
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
sourcemap: false,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
cesium: ['cesium']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
define: {
|
||||
CESIUM_BASE_URL: JSON.stringify('/cesium/')
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user