|
@@ -41,7 +41,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { ref, computed, onUnmounted, watch, nextTick } from "vue";
|
|
|
|
|
|
|
+import { ref, computed, onUnmounted, watch, nextTick, onMounted } from "vue";
|
|
|
import { IRON_BULL_LIST } from "@canal/base";
|
|
import { IRON_BULL_LIST } from "@canal/base";
|
|
|
|
|
|
|
|
const mapContainer = ref(null);
|
|
const mapContainer = ref(null);
|
|
@@ -53,7 +53,10 @@ const currentX = ref(0);
|
|
|
const currentY = ref(0);
|
|
const currentY = ref(0);
|
|
|
const activeIndex = ref(-1);
|
|
const activeIndex = ref(-1);
|
|
|
const enableTransition = ref(false);
|
|
const enableTransition = ref(false);
|
|
|
-const POSITIONS = {
|
|
|
|
|
|
|
+const ORIGINAL_IMAGE_WIDTH = 2752; // 原始图片宽度(px)
|
|
|
|
|
+
|
|
|
|
|
+// 原始坐标(基于 2752px 宽度)
|
|
|
|
|
+const ORIGINAL_POSITIONS = {
|
|
|
0: {
|
|
0: {
|
|
|
x: -17,
|
|
x: -17,
|
|
|
y: 380,
|
|
y: 380,
|
|
@@ -76,6 +79,24 @@ const POSITIONS = {
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// 根据图片实际渲染尺寸动态计算坐标
|
|
|
|
|
+const POSITIONS = computed(() => {
|
|
|
|
|
+ if (!mapImage.value) return ORIGINAL_POSITIONS;
|
|
|
|
|
+
|
|
|
|
|
+ const actualWidth = mapImage.value.getBoundingClientRect().width;
|
|
|
|
|
+ const scale = actualWidth / ORIGINAL_IMAGE_WIDTH;
|
|
|
|
|
+
|
|
|
|
|
+ const positions = {};
|
|
|
|
|
+ Object.keys(ORIGINAL_POSITIONS).forEach((key) => {
|
|
|
|
|
+ positions[key] = {
|
|
|
|
|
+ x: ORIGINAL_POSITIONS[key].x * scale,
|
|
|
|
|
+ y: ORIGINAL_POSITIONS[key].y * scale,
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return positions;
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
const imageStyle = computed(() => {
|
|
const imageStyle = computed(() => {
|
|
|
return {
|
|
return {
|
|
|
transform: `translate(${currentX.value}px, ${currentY.value}px)`,
|
|
transform: `translate(${currentX.value}px, ${currentY.value}px)`,
|
|
@@ -96,6 +117,21 @@ const handleMouseDown = (e) => {
|
|
|
document.addEventListener("mouseup", handleMouseUp);
|
|
document.addEventListener("mouseup", handleMouseUp);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const DESIGN_VIEWPORT_WIDTH = 1920;
|
|
|
|
|
+const MAP_OFFSET_X_RATIO = 395 / DESIGN_VIEWPORT_WIDTH;
|
|
|
|
|
+const MAP_OFFSET_Y_RATIO = 30 / DESIGN_VIEWPORT_WIDTH;
|
|
|
|
|
+
|
|
|
|
|
+const getMapOffsets = () => {
|
|
|
|
|
+ const fallback = { offsetX: 395, offsetY: 30 };
|
|
|
|
|
+ if (!mapContainer.value) return fallback;
|
|
|
|
|
+
|
|
|
|
|
+ const { width } = mapContainer.value.getBoundingClientRect();
|
|
|
|
|
+ return {
|
|
|
|
|
+ offsetX: width * MAP_OFFSET_X_RATIO,
|
|
|
|
|
+ offsetY: width * MAP_OFFSET_Y_RATIO,
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const handleMouseMove = (e) => {
|
|
const handleMouseMove = (e) => {
|
|
|
if (!isDragging.value) return;
|
|
if (!isDragging.value) return;
|
|
|
|
|
|
|
@@ -107,15 +143,17 @@ const handleMouseMove = (e) => {
|
|
|
const containerRect = mapContainer.value.getBoundingClientRect();
|
|
const containerRect = mapContainer.value.getBoundingClientRect();
|
|
|
const imageRect = mapImage.value.getBoundingClientRect();
|
|
const imageRect = mapImage.value.getBoundingClientRect();
|
|
|
|
|
|
|
|
|
|
+ const { offsetX, offsetY } = getMapOffsets();
|
|
|
|
|
+
|
|
|
// 获取图片的实际尺寸(考虑缩放)
|
|
// 获取图片的实际尺寸(考虑缩放)
|
|
|
- const imageWidth = imageRect.width + 395;
|
|
|
|
|
- const imageHeight = imageRect.height + 30;
|
|
|
|
|
|
|
+ const imageWidthValue = imageRect.width + offsetX;
|
|
|
|
|
+ const imageHeight = imageRect.height + offsetY;
|
|
|
const containerWidth = containerRect.width;
|
|
const containerWidth = containerRect.width;
|
|
|
const containerHeight = containerRect.height;
|
|
const containerHeight = containerRect.height;
|
|
|
|
|
|
|
|
// 计算允许的最大和最小偏移量
|
|
// 计算允许的最大和最小偏移量
|
|
|
const maxX = 0;
|
|
const maxX = 0;
|
|
|
- const minX = containerWidth - imageWidth;
|
|
|
|
|
|
|
+ const minX = containerWidth - imageWidthValue;
|
|
|
const maxY = 0;
|
|
const maxY = 0;
|
|
|
const minY = containerHeight - imageHeight;
|
|
const minY = containerHeight - imageHeight;
|
|
|
|
|
|
|
@@ -140,8 +178,10 @@ const centerOnPoint = (index) => {
|
|
|
const containerRect = mapContainer.value.getBoundingClientRect();
|
|
const containerRect = mapContainer.value.getBoundingClientRect();
|
|
|
const imageRect = mapImage.value.getBoundingClientRect();
|
|
const imageRect = mapImage.value.getBoundingClientRect();
|
|
|
|
|
|
|
|
- const imageWidth = imageRect.width + 395;
|
|
|
|
|
- const imageHeight = imageRect.height + 30;
|
|
|
|
|
|
|
+ const { offsetX, offsetY } = getMapOffsets();
|
|
|
|
|
+
|
|
|
|
|
+ const imageWidthValue = imageRect.width + offsetX;
|
|
|
|
|
+ const imageHeight = imageRect.height + offsetY;
|
|
|
const containerWidth = containerRect.width;
|
|
const containerWidth = containerRect.width;
|
|
|
const containerHeight = containerRect.height;
|
|
const containerHeight = containerRect.height;
|
|
|
|
|
|
|
@@ -150,12 +190,12 @@ const centerOnPoint = (index) => {
|
|
|
const centerY = containerHeight / 2;
|
|
const centerY = containerHeight / 2;
|
|
|
|
|
|
|
|
// 计算目标位置:让点位于容器中心
|
|
// 计算目标位置:让点位于容器中心
|
|
|
- const targetX = centerX - POSITIONS[index].x - 395;
|
|
|
|
|
- const targetY = centerY - POSITIONS[index].y;
|
|
|
|
|
|
|
+ const targetX = centerX - POSITIONS.value[index].x - offsetX;
|
|
|
|
|
+ const targetY = centerY - POSITIONS.value[index].y;
|
|
|
|
|
|
|
|
// 计算允许的最大和最小偏移量
|
|
// 计算允许的最大和最小偏移量
|
|
|
const maxX = 0;
|
|
const maxX = 0;
|
|
|
- const minX = containerWidth - imageWidth;
|
|
|
|
|
|
|
+ const minX = containerWidth - imageWidthValue;
|
|
|
const maxY = 0;
|
|
const maxY = 0;
|
|
|
const minY = containerHeight - imageHeight;
|
|
const minY = containerHeight - imageHeight;
|
|
|
|
|
|
|
@@ -171,15 +211,26 @@ const centerOnPoint = (index) => {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const handleResize = () => {
|
|
|
|
|
+ if (activeIndex.value !== -1) {
|
|
|
|
|
+ centerOnPoint(activeIndex.value);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
watch(activeIndex, (newIndex) => {
|
|
watch(activeIndex, (newIndex) => {
|
|
|
if (newIndex !== -1) {
|
|
if (newIndex !== -1) {
|
|
|
centerOnPoint(newIndex);
|
|
centerOnPoint(newIndex);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ window.addEventListener("resize", handleResize);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
|
document.removeEventListener("mouseup", handleMouseUp);
|
|
document.removeEventListener("mouseup", handleMouseUp);
|
|
|
|
|
+ window.removeEventListener("resize", handleResize);
|
|
|
});
|
|
});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|