|
@@ -2,19 +2,26 @@
|
|
|
<div class="home-map">
|
|
<div class="home-map">
|
|
|
<div class="home-map-sidebar">
|
|
<div class="home-map-sidebar">
|
|
|
<div class="home-map-sidebar__title">
|
|
<div class="home-map-sidebar__title">
|
|
|
- <p>铁牛类</p>
|
|
|
|
|
|
|
+ <p>{{ LIST[activeCategory].label }}</p>
|
|
|
<!-- <p>镇水兽所在城市地图</p> -->
|
|
<!-- <p>镇水兽所在城市地图</p> -->
|
|
|
|
|
+ <div class="left" @click="handleCategory(-1)" />
|
|
|
|
|
+ <div class="right" @click="handleCategory(1)" />
|
|
|
</div>
|
|
</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>
|
|
|
|
|
|
|
|
<div class="home-map-map" ref="mapContainer">
|
|
<div class="home-map-map" ref="mapContainer">
|
|
@@ -25,14 +32,18 @@
|
|
|
v-if="activeIndex !== -1"
|
|
v-if="activeIndex !== -1"
|
|
|
class="home-map-map-point"
|
|
class="home-map-map-point"
|
|
|
:style="{
|
|
: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">
|
|
<div class="home-map-map-point-label">
|
|
|
- {{ IRON_BULL_LIST[activeIndex].city }}
|
|
|
|
|
|
|
+ {{ LIST[activeCategory].list[activeIndex].city }}
|
|
|
</div>
|
|
</div>
|
|
|
<el-scrollbar class="home-map-map-point-content">
|
|
<el-scrollbar class="home-map-map-point-content">
|
|
|
- {{ IRON_BULL_LIST[activeIndex].desc }}
|
|
|
|
|
|
|
+ {{ LIST[activeCategory].list[activeIndex].desc }}
|
|
|
</el-scrollbar>
|
|
</el-scrollbar>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -42,8 +53,26 @@
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, computed, onUnmounted, watch, nextTick, onMounted } from "vue";
|
|
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 mapContainer = ref(null);
|
|
|
const mapImage = ref(null);
|
|
const mapImage = ref(null);
|
|
|
const isDragging = ref(false);
|
|
const isDragging = ref(false);
|
|
@@ -57,26 +86,34 @@ const ORIGINAL_IMAGE_WIDTH = 2752; // 原始图片宽度(px)
|
|
|
|
|
|
|
|
// 原始坐标(基于 2752px 宽度)
|
|
// 原始坐标(基于 2752px 宽度)
|
|
|
const ORIGINAL_POSITIONS = {
|
|
const ORIGINAL_POSITIONS = {
|
|
|
- 0: {
|
|
|
|
|
|
|
+ 北京: {
|
|
|
x: -17,
|
|
x: -17,
|
|
|
y: 380,
|
|
y: 380,
|
|
|
},
|
|
},
|
|
|
- 1: {
|
|
|
|
|
|
|
+ 济宁: {
|
|
|
x: 967,
|
|
x: 967,
|
|
|
y: 445,
|
|
y: 445,
|
|
|
},
|
|
},
|
|
|
- 2: {
|
|
|
|
|
- x: 1499,
|
|
|
|
|
- y: 275,
|
|
|
|
|
|
|
+ 聊城: {
|
|
|
|
|
+ x: 787,
|
|
|
|
|
+ y: 462,
|
|
|
|
|
+ },
|
|
|
|
|
+ 泰安: {
|
|
|
|
|
+ x: 837,
|
|
|
|
|
+ y: 292,
|
|
|
},
|
|
},
|
|
|
- 3: {
|
|
|
|
|
|
|
+ 淮安: {
|
|
|
x: 1499,
|
|
x: 1499,
|
|
|
y: 275,
|
|
y: 275,
|
|
|
},
|
|
},
|
|
|
- 4: {
|
|
|
|
|
|
|
+ 扬州: {
|
|
|
x: 1747,
|
|
x: 1747,
|
|
|
y: 285,
|
|
y: 285,
|
|
|
},
|
|
},
|
|
|
|
|
+ 杭州: {
|
|
|
|
|
+ x: 2362,
|
|
|
|
|
+ y: 130,
|
|
|
|
|
+ },
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 根据图片实际渲染尺寸动态计算坐标
|
|
// 根据图片实际渲染尺寸动态计算坐标
|
|
@@ -190,8 +227,12 @@ const centerOnPoint = (index) => {
|
|
|
const centerY = containerHeight / 2;
|
|
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;
|
|
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) => {
|
|
watch(activeIndex, (newIndex) => {
|
|
|
if (newIndex !== -1) {
|
|
if (newIndex !== -1) {
|
|
|
centerOnPoint(newIndex);
|
|
centerOnPoint(newIndex);
|