diff --git a/src/components/map-toolbar.vue b/src/components/map-toolbar.vue
index a79f396..f7e6d74 100644
--- a/src/components/map-toolbar.vue
+++ b/src/components/map-toolbar.vue
@@ -3,6 +3,7 @@ import type { EditorService } from '@core/editor.service';
import { useToolbar } from '@core/useToolbar';
import { computed, inject, type InjectionKey, onBeforeUnmount, onMounted, ref, type ShallowRef } from 'vue';
+import { useViewState } from '../services/useViewState';
import ColorConfigPanel from './color/color-config-panel.vue';
// 通用地图工具栏(右下角),临时中文按钮
@@ -21,14 +22,11 @@ const editorRef = inject(props.token)!;
// 颜色配置面板状态
const showColorConfig = ref(false);
-// 使用 useToolbar 的相关能力(内部使用 jumpToPosition、修改 store 等)
-const {
- toggleGrid: _toggleGrid,
- toggleRule: _toggleRule,
- // fitView: _fitView,
- zoomIn: _zoomIn,
- zoomOut: _zoomOut,
-} = useToolbar();
+// 使用 useToolbar 的相关能力
+const { toggleGrid: _toggleGrid, toggleRule: _toggleRule, zoomIn: _zoomIn, zoomOut: _zoomOut } = useToolbar();
+
+// 使用 useViewState 的相关能力
+const { jumpToPosition, calculateCenterPoint } = useViewState();
const zoomIn = () => {
if (editorRef.value) _zoomIn(editorRef.value);
@@ -36,42 +34,16 @@ const zoomIn = () => {
const zoomOut = () => {
if (editorRef.value) _zoomOut(editorRef.value);
};
-// const fitView = async () => {
-// if (editorRef.value) await _fitView(editorRef.value);
-// };
-// const toggleFullscreen = async () => {
-// try {
-// const el = props.containerEl || document.documentElement;
-// if (!document.fullscreenElement) {
-// await el.requestFullscreen?.();
-// } else {
-// await document.exitFullscreen?.();
-// }
-// } catch (e) {
-// console.warn('全屏切换失败', e);
-// }
-// };
+// 定位到中心点并缩放
+const locateCenter = () => {
+ if (editorRef.value) {
+ const { centerX, centerY } = calculateCenterPoint(editorRef.value);
+ jumpToPosition(editorRef.value, centerX, centerY, false, 0.05);
+ }
+};
-// const downloadBase64 = (base64: string, filename = 'map.png') => {
-// const a = document.createElement('a');
-// a.href = base64;
-// a.download = filename;
-// document.body.appendChild(a);
-// a.click();
-// document.body.removeChild(a);
-// };
-
-// const exportImage = () => {
-// try {
-// const base64 = editorRef.value?.toPng?.(2);
-// if (base64) downloadBase64(base64, '地图截图.png');
-// } catch (e) {
-// console.warn('截图失败', e);
-// }
-// };
-
-// 网格/标尺开关:调用 useToolbar 封装
+// 网格/标尺开关
const toggleGrid = () => editorRef.value && _toggleGrid(editorRef.value);
const toggleRule = () => editorRef.value && _toggleRule(editorRef.value);
@@ -176,7 +148,7 @@ defineOptions({
-
+ 定位
-
-
diff --git a/src/services/useViewState.ts b/src/services/useViewState.ts
index 06426cc..04fe6f8 100644
--- a/src/services/useViewState.ts
+++ b/src/services/useViewState.ts
@@ -205,16 +205,21 @@ export function useViewState() {
* @param x X坐标
* @param y Y坐标
* @param isRestoring 是否为恢复视图状态,true时保持当前缩放比例
+ * @param scale 目标缩放比例
*/
- const jumpToPosition = async (editor: EditorService, x: number, y: number, isRestoring = false): Promise => {
+ const jumpToPosition = async (
+ editor: EditorService,
+ x: number,
+ y: number,
+ isRestoring = false,
+ scale?: number,
+ ): Promise => {
try {
- // 检查是否已存在临时点
- const existingTempPoints = editor
- .find('point')
- .filter((point) => point.id && point.id.includes('view-center-point'));
-
- // 如果不是恢复状态且没有临时点,调整缩放比例到8%
- if (!isRestoring && existingTempPoints.length === 0) {
+ // 如果传递了 scale,则无论如何都应用缩放
+ if (typeof scale === 'number') {
+ editor.scale(scale);
+ } else if (!isRestoring) {
+ // 仅在非恢复状态且未指定 scale 时使用默认缩放
editor.scale(0.08);
}
@@ -239,16 +244,15 @@ export function useViewState() {
editor.inactive();
}, 10); // 短暂延迟确保跳转完成
- // 延迟清理临时点(保存时已自动过滤,这里只是为了清理画布显示)
+ // 延迟清理临时点
setTimeout(() => {
const remainingPoints = editor
.find('point')
.filter((point) => point.id && point.id.includes('view-center-point'));
- if (remainingPoints && remainingPoints.length > 0) {
+ if (remainingPoints.length > 0) {
editor.delete(remainingPoints);
- console.log(`清理了 ${remainingPoints.length} 个临时点`);
}
- }, 500); // 增加延迟确保跳转完成
+ }, 500);
} catch (error) {
console.error('跳转到指定位置失败:', error);
}
@@ -291,8 +295,6 @@ export function useViewState() {
/**
* 自动保存和恢复视图状态
- * 如果本地没有保存的key,则先保存当前状态(用于定位地图),然后恢复
- * 如果有key,则直接按原来逻辑恢复
* @param editor 编辑器服务实例
* @param sceneId 场景ID
* @param groupId 群组ID (可选)
@@ -306,30 +308,17 @@ export function useViewState() {
const hasExistingState = hasViewState(sceneId, groupId);
if (!hasExistingState) {
- // 首次进入:先居中显示获取中心点坐标
editor.centerView();
-
- // 等待一小段时间让centerView完成
await new Promise((resolve) => setTimeout(resolve, 100));
-
- // 获取当前视图状态(主要是为了获取中心点坐标)
const currentState = getCurrentViewState(editor);
-
- // 缩放到8%并跳转到中心点(首次进入的默认行为)
await jumpToPosition(editor, currentState.centerX, currentState.centerY, false);
-
- // 保存当前状态(包含8%缩放和中心点坐标)
await saveViewState(editor, sceneId, groupId);
-
return true;
} else {
- // 直接恢复已有状态
return await restoreViewState(editor, sceneId, groupId);
}
} catch (error) {
console.error('自动保存和恢复视图状态失败:', error);
-
- // 如果出错,至少执行centerView作为fallback
editor.centerView();
return false;
}
@@ -345,7 +334,7 @@ export function useViewState() {
getViewStateInfo,
getCurrentViewState,
autoSaveAndRestoreViewState,
- // 对外暴露跳转方法,供工具栏或其他模块使用(例如适配视图时用该方法居中跳转)
jumpToPosition,
+ calculateCenterPoint,
};
}