|
@@ -37,7 +37,11 @@
|
|
|
<p
|
|
|
>最后更新: <span>{{ lastUpdate }}</span></p
|
|
|
>
|
|
|
- <button class="reset-button" @click="resetView" :disabled="isLoading"> 重置视图 </button>
|
|
|
+ <a-space class="control-space" :size="12">
|
|
|
+ <ZoomInOutlined @click="zoomIn" :disabled="isLoading" title="放大" />
|
|
|
+ <RedoOutlined @click="resetView" :disabled="isLoading" title="重置" />
|
|
|
+ <ZoomOutOutlined @click="zoomOut" :disabled="isLoading" title="缩小" />
|
|
|
+ </a-space>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -54,6 +58,7 @@ import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
|
|
|
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'
|
|
|
import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js'
|
|
|
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'
|
|
|
+import { ZoomInOutlined, ZoomOutOutlined, RedoOutlined } from '@ant-design/icons-vue'
|
|
|
|
|
|
// 定义组件名称
|
|
|
defineOptions({
|
|
@@ -213,8 +218,8 @@ async function initThreeJs() {
|
|
|
try {
|
|
|
// 创建场景
|
|
|
scene = new THREE.Scene()
|
|
|
- scene.background = new THREE.Color(0x000104) // 深色背景
|
|
|
- scene.fog = new THREE.FogExp2(0x000104, 0.0000675) // 雾化效果
|
|
|
+ scene.background = new THREE.Color(0x262d47) // 背景 0x262d47
|
|
|
+ scene.fog = new THREE.FogExp2(0x262d47, 0.0000675) // 雾化效果
|
|
|
|
|
|
// 创建透视相机
|
|
|
camera = new THREE.PerspectiveCamera(45, width / height, 1, 50000)
|
|
@@ -243,11 +248,11 @@ async function initThreeJs() {
|
|
|
setupCameraAndControls()
|
|
|
|
|
|
// 添加环境光
|
|
|
- const ambientLight = new THREE.AmbientLight(0x404040, 1.2)
|
|
|
+ const ambientLight = new THREE.AmbientLight(0x334455, 1.5) // 冷色调环境光
|
|
|
scene.add(ambientLight)
|
|
|
|
|
|
// 添加方向光
|
|
|
- const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2)
|
|
|
+ const directionalLight = new THREE.DirectionalLight(0x88ccff, 1.5) // 冷白光
|
|
|
directionalLight.position.set(500, 1000, 500) // 放置在斜上方
|
|
|
scene.add(directionalLight)
|
|
|
|
|
@@ -357,6 +362,43 @@ function resetView() {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 放大视图
|
|
|
+ */
|
|
|
+function zoomIn() {
|
|
|
+ if (!controls || !camera) return
|
|
|
+
|
|
|
+ // 获取当前相机到目标点的距离
|
|
|
+ const currentDistance = controls.getDistance()
|
|
|
+ // 计算新的距离(缩小10%)
|
|
|
+ const newDistance = Math.max(currentDistance * 0.9, controls.minDistance)
|
|
|
+ // 设置新的距离
|
|
|
+ // OrbitControls 没有 setDistance 方法,通过调整相机位置实现缩放
|
|
|
+ if (controls && camera) {
|
|
|
+ const direction = new THREE.Vector3().subVectors(camera.position, controls.target).normalize()
|
|
|
+ camera.position.copy(controls.target).addScaledVector(direction, newDistance)
|
|
|
+ controls.update()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 缩小视图
|
|
|
+ */
|
|
|
+function zoomOut() {
|
|
|
+ if (!controls || !camera) return
|
|
|
+
|
|
|
+ // 获取当前相机到目标点的距离
|
|
|
+ const currentDistance = controls.getDistance()
|
|
|
+ // 计算新的距离(放大10%)
|
|
|
+ const newDistance = Math.min(currentDistance * 1.1, controls.maxDistance)
|
|
|
+ // 设置新的距离
|
|
|
+ if (controls && camera) {
|
|
|
+ const direction = new THREE.Vector3().subVectors(camera.position, controls.target).normalize()
|
|
|
+ camera.position.copy(controls.target).addScaledVector(direction, newDistance)
|
|
|
+ controls.update()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
* 创建房间的玻璃墙壁
|
|
|
*/
|
|
|
function createRoom() {
|
|
@@ -366,10 +408,12 @@ function createRoom() {
|
|
|
|
|
|
// 透明墙壁材质
|
|
|
const glassMat = new THREE.MeshStandardMaterial({
|
|
|
- color: 0xd1eaff,
|
|
|
+ color: 0x00e5ff, // 亮青色
|
|
|
transparent: true,
|
|
|
opacity: 0.25,
|
|
|
side: THREE.DoubleSide,
|
|
|
+ emissive: 0x00ccff, // 电光蓝发光效果
|
|
|
+ emissiveIntensity: 0.5,
|
|
|
})
|
|
|
|
|
|
// 后墙
|
|
@@ -401,6 +445,25 @@ function createRoom() {
|
|
|
room.add(rightWall)
|
|
|
glassWalls.push(rightWall)
|
|
|
|
|
|
+ // 为墙壁添加边框
|
|
|
+ const edgeMaterial = new THREE.LineBasicMaterial({
|
|
|
+ color: 0x66ffff, // 浅青色边框
|
|
|
+ linewidth: 1,
|
|
|
+ })
|
|
|
+
|
|
|
+ // 后墙边框
|
|
|
+ const backWallEdges = new THREE.EdgesGeometry(backWall.geometry)
|
|
|
+ const backWallWireframe = new THREE.LineSegments(backWallEdges, edgeMaterial)
|
|
|
+ backWall.add(backWallWireframe)
|
|
|
+ // 左墙边框
|
|
|
+ const leftWallEdges = new THREE.EdgesGeometry(leftWall.geometry)
|
|
|
+ const leftWallWireframe = new THREE.LineSegments(leftWallEdges, edgeMaterial)
|
|
|
+ leftWall.add(leftWallWireframe)
|
|
|
+ // 右墙边框
|
|
|
+ const rightWallEdges = new THREE.EdgesGeometry(rightWall.geometry)
|
|
|
+ const rightWallWireframe = new THREE.LineSegments(rightWallEdges, edgeMaterial)
|
|
|
+ rightWall.add(rightWallWireframe)
|
|
|
+
|
|
|
scene.add(room)
|
|
|
}
|
|
|
|
|
@@ -417,11 +480,13 @@ function createFloorPoints() {
|
|
|
floorPoints = new THREE.Points(
|
|
|
geometry,
|
|
|
new THREE.PointsMaterial({
|
|
|
- color: 0x336699,
|
|
|
+ color: 0x667788, // 电光蓝 0x00ccff
|
|
|
size: 10,
|
|
|
+ transparent: true,
|
|
|
+ opacity: 0.3,
|
|
|
})
|
|
|
)
|
|
|
- floorPoints.position.y = -10
|
|
|
+ floorPoints.position.y = -1 // 墙壁与地面的间距
|
|
|
floorPoints.rotation.x = -Math.PI / 2
|
|
|
scene.add(floorPoints)
|
|
|
}
|
|
@@ -450,7 +515,7 @@ function setupPostProcessing(width: number, height: number) {
|
|
|
// 添加Bloom效果
|
|
|
if (typeof BloomPass !== 'undefined') {
|
|
|
try {
|
|
|
- const effectBloom = new BloomPass(0.4)
|
|
|
+ const effectBloom = new BloomPass(0.8, 25, 4) // 增强发光效果
|
|
|
composer.addPass(effectBloom)
|
|
|
} catch (error) {
|
|
|
console.warn('Bloom效果初始化失败,已跳过', error)
|
|
@@ -816,8 +881,7 @@ onUnmounted(() => {
|
|
|
.overlay {
|
|
|
position: absolute;
|
|
|
top: 10px;
|
|
|
- left: 10px;
|
|
|
- background: rgba(0, 0, 0, 0.7);
|
|
|
+ right: 10px;
|
|
|
color: white;
|
|
|
padding: 10px;
|
|
|
border-radius: 5px;
|
|
@@ -837,20 +901,11 @@ onUnmounted(() => {
|
|
|
border-radius: 3px;
|
|
|
}
|
|
|
|
|
|
-.reset-button {
|
|
|
- margin-top: 10px;
|
|
|
- padding: 6px 12px;
|
|
|
- background-color: #3498db;
|
|
|
- color: white;
|
|
|
- border: none;
|
|
|
- border-radius: 4px;
|
|
|
+.control-space {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 24px;
|
|
|
cursor: pointer;
|
|
|
- font-size: 14px;
|
|
|
- transition: background-color 0.2s;
|
|
|
-}
|
|
|
-
|
|
|
-.reset-button:hover {
|
|
|
- background-color: #2980b9;
|
|
|
+ font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.reset-button:disabled {
|