chenlei 1 周之前
父节点
当前提交
4c9c802898

文件差异内容过多而无法显示
+ 23 - 8
packages/base/src/constants.js


二进制
packages/pc/src/views/Home/images/tab-large-a-min.png


二进制
packages/pc/src/views/Home/images/tab-large-min.png


+ 38 - 8
packages/pc/src/views/Home/map.scss

@@ -20,15 +20,33 @@
   &-sidebar {
     position: absolute;
     top: 122px;
-    left: 166px;
-    width: 244px;
+    left: 140px;
+    width: 295px;
     z-index: 2;
 
     &__title {
+      position: relative;
       color: #5c431c;
       font-size: 37px;
       text-align: center;
+      width: max-content;
+      margin: 0 auto;
 
+      .left,
+      .right {
+        position: absolute;
+        top: 50%;
+        width: 50px;
+        height: 50px;
+        cursor: pointer;
+        transform: translateY(-50%);
+      }
+      .left {
+        left: -55px;
+      }
+      .right {
+        right: -55px;
+      }
       p:first-child {
         position: relative;
 
@@ -42,11 +60,11 @@
           transform: translateY(-50%);
         }
         &::before {
-          left: -151px;
+          left: -201px;
           background: url("./images/left-min.png") no-repeat center / contain;
         }
         &::after {
-          right: -151px;
+          right: -201px;
           background: url("./images/right-min.png") no-repeat center / contain;
         }
       }
@@ -58,12 +76,15 @@
       // }
     }
     &__list {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      gap: 94px;
       margin-top: 110px;
+      height: 800px;
 
+      ul {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        gap: 94px;
+      }
       li {
         width: 190px;
         line-height: 46px;
@@ -74,9 +95,18 @@
         background: url("./images/tab-min.png") no-repeat center / contain;
         cursor: pointer;
 
+        &.is-large {
+          width: 295px;
+          background-image: url("./images/tab-large-min.png");
+        }
+
         &.active {
           color: #e9e6dc;
           background-image: url("./images/tab-a-min.png");
+
+          &.is-large {
+            background-image: url("./images/tab-large-a-min.png");
+          }
         }
       }
     }

+ 76 - 24
packages/pc/src/views/Home/map.vue

@@ -2,19 +2,26 @@
   <div class="home-map">
     <div class="home-map-sidebar">
       <div class="home-map-sidebar__title">
-        <p>铁牛类</p>
+        <p>{{ LIST[activeCategory].label }}</p>
         <!-- <p>镇水兽所在城市地图</p> -->
+        <div class="left" @click="handleCategory(-1)" />
+        <div class="right" @click="handleCategory(1)" />
       </div>
-      <ul class="home-map-sidebar__list">
-        <li
-          v-for="(item, index) in IRON_BULL_LIST"
-          :key="item.name"
-          :class="{ active: activeIndex === index }"
-          @click="activeIndex = index"
-        >
-          <p>{{ item.name }}</p>
-        </li>
-      </ul>
+      <el-scrollbar class="home-map-sidebar__list">
+        <ul>
+          <li
+            v-for="(item, index) in LIST[activeCategory].list"
+            :key="item.realName"
+            :class="{
+              active: activeIndex === index,
+              'is-large': isLargeTab(item),
+            }"
+            @click="activeIndex = index"
+          >
+            <p>{{ getItemLabel(item) }}</p>
+          </li>
+        </ul>
+      </el-scrollbar>
     </div>
 
     <div class="home-map-map" ref="mapContainer">
@@ -25,14 +32,18 @@
           v-if="activeIndex !== -1"
           class="home-map-map-point"
           :style="{
-            transform: `translate(${POSITIONS[activeIndex].x}px, ${POSITIONS[activeIndex].y}px)`,
+            transform: `translate(${
+              POSITIONS[LIST[activeCategory].list[activeIndex].city].x
+            }px, ${
+              POSITIONS[LIST[activeCategory].list[activeIndex].city].y
+            }px)`,
           }"
         >
           <div class="home-map-map-point-label">
-            {{ IRON_BULL_LIST[activeIndex].city }}
+            {{ LIST[activeCategory].list[activeIndex].city }}
           </div>
           <el-scrollbar class="home-map-map-point-content">
-            {{ IRON_BULL_LIST[activeIndex].desc }}
+            {{ LIST[activeCategory].list[activeIndex].desc }}
           </el-scrollbar>
         </div>
       </div>
@@ -42,8 +53,26 @@
 
 <script setup>
 import { ref, computed, onUnmounted, watch, nextTick, onMounted } from "vue";
-import { IRON_BULL_LIST } from "@canal/base";
+import { IRON_BULL_LIST, MONSTER_LIST, BUILDING_LIST } from "@canal/base";
+
+const getItemLabel = (item) => item?.name || item?.realName || "";
+const isLargeTab = (item) => getItemLabel(item).length > 6;
 
+const LIST = [
+  {
+    label: "铁牛类",
+    list: IRON_BULL_LIST,
+  },
+  {
+    label: "神兽类",
+    list: MONSTER_LIST,
+  },
+  {
+    label: "器物、建筑类",
+    list: BUILDING_LIST,
+  },
+];
+const activeCategory = ref(0);
 const mapContainer = ref(null);
 const mapImage = ref(null);
 const isDragging = ref(false);
@@ -57,26 +86,34 @@ const ORIGINAL_IMAGE_WIDTH = 2752; // 原始图片宽度(px)
 
 // 原始坐标(基于 2752px 宽度)
 const ORIGINAL_POSITIONS = {
-  0: {
+  北京: {
     x: -17,
     y: 380,
   },
-  1: {
+  济宁: {
     x: 967,
     y: 445,
   },
-  2: {
-    x: 1499,
-    y: 275,
+  聊城: {
+    x: 787,
+    y: 462,
+  },
+  泰安: {
+    x: 837,
+    y: 292,
   },
-  3: {
+  淮安: {
     x: 1499,
     y: 275,
   },
-  4: {
+  扬州: {
     x: 1747,
     y: 285,
   },
+  杭州: {
+    x: 2362,
+    y: 130,
+  },
 };
 
 // 根据图片实际渲染尺寸动态计算坐标
@@ -190,8 +227,12 @@ const centerOnPoint = (index) => {
     const centerY = containerHeight / 2;
 
     // 计算目标位置:让点位于容器中心
-    const targetX = centerX - POSITIONS.value[index].x - offsetX;
-    const targetY = centerY - POSITIONS.value[index].y;
+    const targetX =
+      centerX -
+      POSITIONS.value[LIST[activeCategory.value].list[index].city].x -
+      offsetX;
+    const targetY =
+      centerY - POSITIONS.value[LIST[activeCategory.value].list[index].city].y;
 
     // 计算允许的最大和最小偏移量
     const maxX = 0;
@@ -217,6 +258,17 @@ const handleResize = () => {
   }
 };
 
+const handleCategory = (direction) => {
+  let val = activeCategory.value + direction;
+  if (val < 0) {
+    val = LIST.length - 1;
+  } else if (val >= LIST.length) {
+    val = 0;
+  }
+  activeIndex.value = -1;
+  activeCategory.value = val;
+};
+
 watch(activeIndex, (newIndex) => {
   if (newIndex !== -1) {
     centerOnPoint(newIndex);

二进制
packages/pc/src/views/Step2/images/card-head-active-min.png