소스 검색

修改过渡动画显示通州区

画安 4 일 전
부모
커밋
a0c93f676b
2개의 변경된 파일61개의 추가작업 그리고 56개의 파일을 삭제
  1. 43 32
      src/components/CesiumTransition.vue
  2. 18 24
      src/views/TransitionPage.vue

+ 43 - 32
src/components/CesiumTransition.vue

@@ -3,6 +3,7 @@
     <div ref="cesiumContainer" class="cesium-container"></div>
     <div class="ui-layer">
       <div
+        v-if="poi"
         ref="poiLabel"
         class="html-label"
         :style="{ color: poi.fontColor || '#00ffff', fontSize: (poi.fontSize || 20) + 'px', opacity: 0, display: 'none' }"
@@ -53,18 +54,15 @@ export default {
       type: String,
       default: '北京市'
     },
-    // 微观标记点
+    // 微观标记点(null 则不显示POI)
     poi: {
       type: Object,
-      default: () => ({
-        lon: 116.22405,
-        lat: 39.90515,
-        label: '鲁谷西街与政达路交叉口',
-        radarRadius: 200,
-        themeColor: '#00bfff',  // CSS 颜色字符串
-        fontColor: '#00ffff',
-        fontSize: 20
-      })
+      default: null
+    },
+    // 区域中心坐标 [lon, lat](无POI时用于相机定位)
+    districtCenter: {
+      type: Array,
+      default: null
     },
     // 路网数据
     roads: {
@@ -156,7 +154,9 @@ export default {
       this._dynamicGold = this._baseGold.withAlpha(0);
       this._dynamicWhite = this._baseWhite.withAlpha(0);
       this._dynamicBlack = this._baseBlack.withAlpha(0);
-      this._poiThemeColor = Cesium.Color.fromCssColorString(this.poi.themeColor || '#00bfff');
+      this._poiThemeColor = Cesium.Color.fromCssColorString(
+        (this.poi && this.poi.themeColor) || '#00bfff'
+      );
 
       // 将 props 中的 roads 转为 Cesium 颜色对象
       this._majorRoads = this.roads.map(r => ({
@@ -203,17 +203,21 @@ export default {
       this.buildMicroLayer();
 
       this._preRenderListener = this._viewer.scene.preRender.addEventListener(() => {
-        if (!this._microEffectsSource || !this._microEffectsSource.show || !this.$refs.poiLabel) return;
-        if (this.$refs.poiLabel.style.opacity === "0") return;
-        const pos3D = Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat);
-        const screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this._viewer.scene, pos3D);
-        if (screenPos && screenPos.y > 0) {
-          this.$refs.poiLabel.style.display = 'flex';
-          this.$refs.poiLabel.style.left = screenPos.x + 'px';
-          this.$refs.poiLabel.style.top = (screenPos.y - 150) + 'px';
-        } else {
-          this.$refs.poiLabel.style.display = 'none';
+        if (!this._microEffectsSource || !this._microEffectsSource.show) return;
+
+        // POI 标签跟踪
+        if (this.poi && this.$refs.poiLabel && this.$refs.poiLabel.style.opacity !== "0") {
+          const pos3D = Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat);
+          const screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this._viewer.scene, pos3D);
+          if (screenPos && screenPos.y > 0) {
+            this.$refs.poiLabel.style.display = 'flex';
+            this.$refs.poiLabel.style.left = screenPos.x + 'px';
+            this.$refs.poiLabel.style.top = (screenPos.y - 150) + 'px';
+          } else {
+            this.$refs.poiLabel.style.display = 'none';
+          }
         }
+
       });
     },
 
@@ -290,15 +294,19 @@ export default {
       this._viewer.dataSources.add(this._microEffectsSource);
       this._microEffectsSource.show = false;
 
-      const pos3D = Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat);
-      const slowRingImg = createOuterRingTexture(this._poiThemeColor);
-      const fastScannerImg = createScannerTexture(this._poiThemeColor);
-      const beamImg = createLightBeamTexture(this._poiThemeColor);
+      // POI 标记(可选)
+      if (this.poi) {
+        const pos3D = Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat);
+        const slowRingImg = createOuterRingTexture(this._poiThemeColor);
+        const fastScannerImg = createScannerTexture(this._poiThemeColor);
+        const beamImg = createLightBeamTexture(this._poiThemeColor);
+
+        this._microEffectsSource.entities.add({ position: pos3D, ellipse: { semiMinorAxis: this.poi.radarRadius, semiMajorAxis: this.poi.radarRadius, material: new Cesium.ImageMaterialProperty({ image: slowRingImg, transparent: true }), stRotation: new Cesium.CallbackProperty(() => (Date.now() / 5000.0) % TWO_PI, false), height: 20 } });
+        this._microEffectsSource.entities.add({ position: pos3D, ellipse: { semiMinorAxis: this.poi.radarRadius, semiMajorAxis: this.poi.radarRadius, material: new Cesium.ImageMaterialProperty({ image: fastScannerImg, transparent: true }), stRotation: new Cesium.CallbackProperty(() => (Date.now() / 300.0) % TWO_PI, false), height: 21 } });
+        this._microEffectsSource.entities.add({ position: Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat, 2000.0), cylinder: { length: 4000, topRadius: 20, bottomRadius: 200, material: new Cesium.ImageMaterialProperty({ image: beamImg, transparent: true }) } });
+        this._microEffectsSource.entities.add({ position: Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat, 50), point: { pixelSize: 15, color: Cesium.Color.WHITE, outlineColor: this._poiThemeColor, outlineWidth: 3 } });
+      }
 
-      this._microEffectsSource.entities.add({ position: pos3D, ellipse: { semiMinorAxis: this.poi.radarRadius, semiMajorAxis: this.poi.radarRadius, material: new Cesium.ImageMaterialProperty({ image: slowRingImg, transparent: true }), stRotation: new Cesium.CallbackProperty(() => (Date.now() / 5000.0) % TWO_PI, false), height: 20 } });
-      this._microEffectsSource.entities.add({ position: pos3D, ellipse: { semiMinorAxis: this.poi.radarRadius, semiMajorAxis: this.poi.radarRadius, material: new Cesium.ImageMaterialProperty({ image: fastScannerImg, transparent: true }), stRotation: new Cesium.CallbackProperty(() => (Date.now() / 300.0) % TWO_PI, false), height: 21 } });
-      this._microEffectsSource.entities.add({ position: Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat, 2000.0), cylinder: { length: 4000, topRadius: 20, bottomRadius: 200, material: new Cesium.ImageMaterialProperty({ image: beamImg, transparent: true }) } });
-      this._microEffectsSource.entities.add({ position: Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat, 50), point: { pixelSize: 15, color: Cesium.Color.WHITE, outlineColor: this._poiThemeColor, outlineWidth: 3 } });
     },
 
     fadeMacroLayer(startAlpha, endAlpha, durationMs) {
@@ -393,18 +401,21 @@ export default {
       if (this._destroyed) return;
 
       // 阶段2: 俯冲到微观
-      const targetSphere = Cesium.BoundingSphere.fromPoints([Cesium.Cartesian3.fromDegrees(this.poi.lon, this.poi.lat)]);
+      const targetCenter = this.poi
+        ? [this.poi.lon, this.poi.lat]
+        : (this.districtCenter || [116.70, 39.80]);
+      const targetSphere = Cesium.BoundingSphere.fromPoints([Cesium.Cartesian3.fromDegrees(targetCenter[0], targetCenter[1])]);
       this._viewer.camera.flyToBoundingSphere(targetSphere, {
         offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(-45), this.microViewRange),
         duration: 2, easingFunction: Cesium.EasingFunction.CUBIC_IN_OUT
       });
       this.fadeMacroLayer(1.0, 0.0, 800);
 
-      // 阶段3: 显示微观雷达 + POI标签
+      // 阶段3: 显示微观效果
       await this._safeDelay(1500);
       if (this._destroyed) return;
       this._microEffectsSource.show = true;
-      if (this.$refs.poiLabel) this.$refs.poiLabel.style.opacity = 1;
+      if (this.poi && this.$refs.poiLabel) this.$refs.poiLabel.style.opacity = 1;
 
       // 阶段4: 路网生长
       await this._safeDelay(300);

+ 18 - 24
src/views/TransitionPage.vue

@@ -5,6 +5,7 @@
         v-if="isTransitioning"
         :province="province"
         :poi="poi"
+        :district-center="districtCenter"
         :roads="roads"
         :satellite-image="satelliteImage"
         :boundary-url="boundaryUrl"
@@ -30,38 +31,31 @@ export default {
       // 高亮的省份
       province: '北京市',
 
-      // 微观标记点
-      poi: {
-        lon: 116.22405,
-        lat: 39.90515,
-        label: '鲁谷西街与政达路交叉口',
-        radarRadius: 200,
-        themeColor: '#00bfff',
-        fontColor: '#00ffff',
-        fontSize: 20
-      },
+      // 微观标记点(null 则不显示POI)
+      poi: null,
 
-      // 路网数据:color 使用 CSS 颜色字符串
+      // 区域中心(用于相机定位)
+      districtCenter: [116.70, 39.80],
+
+      // 路网数据:两横三纵
       roads: [
-        { name: "阜石路-阜成路快速路", width: 12, glowPower: 0.3, color: '#00ffff', path: [[116.18, 39.93], [116.22, 39.93], [116.26, 39.928], [116.30, 39.925]] },
-        { name: "石景山路-复兴路", width: 12, glowPower: 0.3, color: '#ff3333', path: [[116.18, 39.907], [116.224, 39.907], [116.25, 39.906], [116.30, 39.905]] },
-        { name: "莲石东路快速路", width: 12, glowPower: 0.3, color: '#00ff00', path: [[116.18, 39.89], [116.22, 39.888], [116.26, 39.885], [116.30, 39.88]] },
-        { name: "西五环路", width: 10, glowPower: 0.25, color: '#ffaa00', path: [[116.205, 39.95], [116.203, 39.92], [116.202, 39.89], [116.20, 39.86]] },
-        { name: "玉泉路", width: 10, glowPower: 0.25, color: '#cc00ff', path: [[116.25, 39.94], [116.25, 39.907], [116.248, 39.88], [116.245, 39.86]] },
-        { name: "西四环路", width: 10, glowPower: 0.25, color: '#ffff00', path: [[116.285, 39.94], [116.283, 39.91], [116.28, 39.88], [116.278, 39.85]] }
+        // 两横
+        { name: "京通快速路", width: 12, glowPower: 0.3, color: '#00ffff', path: [[116.48, 39.91], [116.55, 39.91], [116.62, 39.905], [116.70, 39.90], [116.78, 39.895], [116.86, 39.89], [116.94, 39.885]] },
+        { name: "京哈高速", width: 12, glowPower: 0.3, color: '#ff3333', path: [[116.48, 39.82], [116.56, 39.82], [116.64, 39.815], [116.72, 39.81], [116.80, 39.805], [116.88, 39.80], [116.94, 39.795]] },
+        // 三纵
+        { name: "六环路(东段)", width: 10, glowPower: 0.25, color: '#ffaa00', path: [[116.58, 39.98], [116.585, 39.94], [116.59, 39.90], [116.59, 39.86], [116.585, 39.82], [116.58, 39.78], [116.58, 39.72]] },
+        { name: "通州北运河大道", width: 10, glowPower: 0.25, color: '#cc00ff', path: [[116.70, 39.98], [116.705, 39.94], [116.71, 39.90], [116.71, 39.86], [116.705, 39.82], [116.70, 39.78], [116.70, 39.72]] },
+        { name: "京津公路", width: 10, glowPower: 0.25, color: '#00ff88', path: [[116.82, 39.98], [116.825, 39.94], [116.83, 39.90], [116.83, 39.86], [116.825, 39.82], [116.82, 39.78], [116.82, 39.72]] }
       ],
 
-      // 微观区域卫星底图
-      satelliteImage: {
-        url: './beijing-satellite.jpg',
-        bounds: [116.10, 39.80, 116.38, 39.98]  // [west, south, east, north]
-      },
+      // 微观区域卫星底图(通州区范围)
+      satelliteImage: null,
 
       // 中国边界 GeoJSON
       boundaryUrl: './china.json',
 
-      // 微观俯冲视角高度(米)
-      microViewRange: 10000
+      // 微观俯冲视角高度(米) — 通州全区需要更高视角
+      microViewRange: 80000
     };
   },
   methods: {