feat:减少冗余代码???

This commit is contained in:
SikongJueluo 2025-07-13 14:48:18 +08:00
parent f710a66c69
commit a76ee74656
No known key found for this signature in database
2 changed files with 190 additions and 147 deletions

View File

@ -40,7 +40,7 @@
ref="canvas"
class="diagram-canvas"
:style="{
transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,
transform: `translate(${componentManager.canvasPosition.x}px, ${componentManager.canvasPosition.y}px) scale(${componentManager.canvasScale.value})`,
}"
>
<!-- 渲染连线 -->
@ -167,7 +167,9 @@
class="absolute bottom-4 right-4 bg-base-100 px-3 py-1.5 rounded-md shadow-md z-20"
style="opacity: 0.9"
>
<span class="text-sm font-medium">{{ Math.round(scale * 100) }}%</span>
<span class="text-sm font-medium"
>{{ Math.round(componentManager?.canvasScale.value * 100) }}%</span
>
</div>
</div>
</template>
@ -243,8 +245,6 @@ const alertStore = useAlertStore();
// --- ---
const canvasContainer = ref<HTMLElement | null>(null);
const canvas = ref<HTMLElement | null>(null);
const position = reactive({ x: 0, y: 0 });
const scale = ref(1);
const isDragging = ref(false);
const isMiddleDragging = ref(false);
const dragStart = reactive({ x: 0, y: 0 });
@ -265,11 +265,6 @@ const diagramData = ref<DiagramData>({
connections: [],
});
// 便
const componentRefs = computed(
() => componentManager?.componentRefs.value || {},
);
// diagramData index
const diagramParts = computed<DiagramPart[]>(() => {
//
@ -423,25 +418,13 @@ function onZoom(e: WheelEvent) {
const mouseX = e.clientX - containerRect.left;
const mouseY = e.clientY - containerRect.top;
//
const mouseXCanvas = (mouseX - position.x) / scale.value;
const mouseYCanvas = (mouseY - position.y) / scale.value;
//
const zoomFactor = 1.1; // /10%
const direction = e.deltaY > 0 ? -1 : 1;
const finalZoomFactor = direction > 0 ? zoomFactor : 1 / zoomFactor;
//
let newScale =
direction > 0 ? scale.value * zoomFactor : scale.value / zoomFactor;
newScale = Math.max(MIN_SCALE, Math.min(newScale, MAX_SCALE));
// 使
position.x = mouseX - mouseXCanvas * newScale;
position.y = mouseY - mouseYCanvas * newScale;
//
scale.value = newScale;
// 使componentManager
componentManager?.zoomAtPosition(mouseX, mouseY, finalZoomFactor);
}
// --- ---
@ -472,8 +455,10 @@ function startDrag(e: MouseEvent) {
isDragging.value = true;
isMiddleDragging.value = false;
dragStart.x = e.clientX - position.x;
dragStart.y = e.clientY - position.y;
const currentPosition = componentManager?.getCanvasPosition();
if (!currentPosition) return;
dragStart.x = e.clientX - currentPosition.x;
dragStart.y = e.clientY - currentPosition.y;
isDragEventActive.value = true;
e.preventDefault();
@ -487,8 +472,10 @@ function startMiddleDrag(e: MouseEvent) {
isDragging.value = false;
draggingComponentId.value = null;
dragStart.x = e.clientX - position.x;
dragStart.y = e.clientY - position.y;
const currentPosition = componentManager?.getCanvasPosition();
if (!currentPosition) return;
dragStart.x = e.clientX - currentPosition.x;
dragStart.y = e.clientY - currentPosition.y;
isDragEventActive.value = true;
e.preventDefault();
@ -498,8 +485,11 @@ function startMiddleDrag(e: MouseEvent) {
function onDrag(e: MouseEvent) {
if (!isDragging.value && !isMiddleDragging.value) return;
position.x = e.clientX - dragStart.x;
position.y = e.clientY - dragStart.y;
const newX = e.clientX - dragStart.x;
const newY = e.clientY - dragStart.y;
// 使componentManager
componentManager?.setCanvasPosition(newX, newY);
}
//
@ -551,15 +541,16 @@ function startComponentDrag(e: MouseEvent, component: DiagramPart) {
if (!canvasContainer.value) return;
const containerRect = canvasContainer.value.getBoundingClientRect();
//
const mouseX_canvas =
(e.clientX - containerRect.left - position.x) / scale.value;
const mouseY_canvas =
(e.clientY - containerRect.top - position.y) / scale.value;
// 使componentManager
const mouseCanvasPos = componentManager?.screenToCanvas(
e.clientX - containerRect.left,
e.clientY - containerRect.top,
);
if (!mouseCanvasPos) return;
//
componentDragOffset.x = mouseX_canvas - component.x;
componentDragOffset.y = mouseY_canvas - component.y;
componentDragOffset.x = mouseCanvasPos.x - component.x;
componentDragOffset.y = mouseCanvasPos.y - component.y;
//
isComponentDragEventActive.value = true;
@ -575,15 +566,16 @@ function onComponentDrag(e: MouseEvent) {
const containerRect = canvasContainer.value.getBoundingClientRect();
//
const mouseX_canvas =
(e.clientX - containerRect.left - position.x) / scale.value;
const mouseY_canvas =
(e.clientY - containerRect.top - position.y) / scale.value;
// 使componentManager
const mouseCanvasPos = componentManager?.screenToCanvas(
e.clientX - containerRect.left,
e.clientY - containerRect.top,
);
if (!mouseCanvasPos) return;
//
const newX = mouseX_canvas - componentDragOffset.x;
const newY = mouseY_canvas - componentDragOffset.y;
const newX = mouseCanvasPos.x - componentDragOffset.x;
const newY = mouseCanvasPos.y - componentDragOffset.y;
//
const draggedComponent = diagramParts.value.find(
@ -671,9 +663,19 @@ function updateComponentProp(
function updateMousePosition(e: MouseEvent) {
if (!canvasContainer.value) return;
const containerRect = canvasContainer.value.getBoundingClientRect();
mousePosition.x = (e.clientX - containerRect.left - position.x) / scale.value;
mousePosition.y = (e.clientY - containerRect.top - position.y) / scale.value;
} //
// 使componentManager
const canvasPos = componentManager?.screenToCanvas(
e.clientX - containerRect.left,
e.clientY - containerRect.top,
);
if (!canvasPos) return;
mousePosition.x = canvasPos.x;
mousePosition.y = canvasPos.y;
}
//
function handlePinClick(componentId: string, pinInfo: any, event: MouseEvent) {
if (!canvasContainer.value) return;
updateMousePosition(event);
@ -1029,8 +1031,8 @@ onMounted(async () => {
saveDiagramData(data);
emit("diagram-updated", data);
},
getCanvasPosition: () => ({ x: position.x, y: position.y }),
getScale: () => scale.value,
getCanvasPosition: () => componentManager.getCanvasPosition(),
getScale: () => componentManager.getCanvasScale(),
$el: canvasContainer.value,
};
componentManager.setCanvasRef(canvasAPI);
@ -1060,11 +1062,13 @@ onMounted(async () => {
} catch (error) {
console.error("加载图表数据失败:", error);
}
//
if (canvasContainer.value) {
// - 使componentManager
if (canvasContainer.value && componentManager) {
//
position.x = canvasContainer.value.clientWidth / 2 - 5000; //
position.y = canvasContainer.value.clientHeight / 2 - 5000; //
const centerX = canvasContainer.value.clientWidth / 2 - 5000; //
const centerY = canvasContainer.value.clientHeight / 2 - 5000; //
componentManager.setCanvasPosition(centerX, centerY);
}
});
@ -1102,40 +1106,6 @@ defineExpose({
//
getDiagramData: () => diagramData.value,
updateDiagramDataDirectly,
setDiagramData: (data: DiagramData) => {
//
if (!document.body.contains(canvasContainer.value)) {
return; //
}
isLoading.value = true;
// 使requestAnimationFrameUI
window.requestAnimationFrame(() => {
//
if (!document.body.contains(canvasContainer.value)) {
return; //
}
diagramData.value = data;
saveDiagramData(data);
// diagram-updated
emit("diagram-updated", data);
// 便UI
setTimeout(() => {
//
if (document.body.contains(canvasContainer.value)) {
isLoading.value = false;
}
}, 200);
});
},
//
getCanvasPosition: () => ({ x: position.x, y: position.y }),
getScale: () => scale.value,
});
// -
@ -1241,15 +1211,6 @@ watch(
display: none;
}
/* 为黑暗模式设置不同的网格线颜色 */
/* :root[data-theme="dark"] .diagram-container {
background-image:
linear-gradient(to right, rgba(200, 200, 200, 0.1) 1px, transparent 1px),
linear-gradient(to bottom, rgba(200, 200, 200, 0.1) 1px, transparent 1px),
linear-gradient(to right, rgba(180, 180, 180, 0.15) 100px, transparent 100px),
linear-gradient(to bottom, rgba(180, 180, 180, 0.15) 100px, transparent 100px);
} */
/* 深度选择器 - 默认阻止SVG内部元素的鼠标事件但允许SVG本身和特定交互元素 */
.component-wrapper :deep(svg) {
pointer-events: auto;

View File

@ -1,4 +1,4 @@
import { ref, shallowRef, computed } from "vue";
import { ref, shallowRef, computed, reactive } from "vue";
import { createInjectionState } from "@vueuse/core";
import type { DiagramData, DiagramPart } from "./diagramManager";
import type { PropertyConfig } from "@/components/equipments/componentConfig";
@ -28,6 +28,10 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
const diagramCanvas = ref<any>(null);
const componentRefs = ref<Record<string, any>>({});
// 新增直接管理canvas的位置和缩放
const canvasPosition = reactive({ x: 0, y: 0 });
const canvasScale = ref(1);
// 计算当前选中的组件数据
const selectedComponentData = computed(() => {
if (!diagramCanvas.value || !selectedComponentId.value) return null;
@ -40,6 +44,104 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
return null;
});
// --- Canvas 控制方法 ---
/**
* canvas位置
*/
function setCanvasPosition(x: number, y: number) {
canvasPosition.x = x;
canvasPosition.y = y;
}
/**
* canvas位置
*/
function updateCanvasPosition(deltaX: number, deltaY: number) {
canvasPosition.x += deltaX;
canvasPosition.y += deltaY;
}
/**
* canvas缩放
*/
function setCanvasScale(scale: number) {
canvasScale.value = Math.max(0.2, Math.min(scale, 10.0));
}
/**
* canvas位置
*/
function getCanvasPosition() {
return { x: canvasPosition.x, y: canvasPosition.y };
}
/**
* canvas缩放
*/
function getCanvasScale() {
return canvasScale.value;
}
/**
*
*/
function zoomAtPosition(mouseX: number, mouseY: number, zoomFactor: number) {
// 计算鼠标在画布坐标系中的位置
const mouseXCanvas = (mouseX - canvasPosition.x) / canvasScale.value;
const mouseYCanvas = (mouseY - canvasPosition.y) / canvasScale.value;
// 计算新的缩放值
const newScale = Math.max(0.2, Math.min(canvasScale.value * zoomFactor, 10.0));
// 计算新的位置,使鼠标指针位置在缩放前后保持不变
canvasPosition.x = mouseX - mouseXCanvas * newScale;
canvasPosition.y = mouseY - mouseYCanvas * newScale;
canvasScale.value = newScale;
return { scale: newScale, position: { x: canvasPosition.x, y: canvasPosition.y } };
}
/**
*
*/
function screenToCanvas(screenX: number, screenY: number) {
return {
x: (screenX - canvasPosition.x) / canvasScale.value,
y: (screenY - canvasPosition.y) / canvasScale.value
};
}
/**
*
*/
function canvasToScreen(canvasX: number, canvasY: number) {
return {
x: canvasX * canvasScale.value + canvasPosition.x,
y: canvasY * canvasScale.value + canvasPosition.y
};
}
/**
*
*/
function centerView(bounds: { x: number, y: number, width: number, height: number }, containerWidth: number, containerHeight: number) {
// 计算合适的缩放比例
const scaleX = containerWidth / bounds.width;
const scaleY = containerHeight / bounds.height;
const newScale = Math.min(scaleX, scaleY, 1) * 0.8; // 留一些边距
// 计算居中位置
const centerX = bounds.x + bounds.width / 2;
const centerY = bounds.y + bounds.height / 2;
canvasScale.value = newScale;
canvasPosition.x = containerWidth / 2 - centerX * newScale;
canvasPosition.y = containerHeight / 2 - centerY * newScale;
return { scale: newScale, position: { x: canvasPosition.x, y: canvasPosition.y } };
}
// --- 组件模块管理 ---
/**
@ -111,23 +213,17 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
}
console.log(`组件模块加载成功: ${componentData.type}`, componentModule);
// 获取画布位置信息
// 使用内部管理的位置和缩放信息
let position = { x: 100, y: 100 };
let scale = 1;
try {
if (canvasInstance.getCanvasPosition && canvasInstance.getScale) {
position = canvasInstance.getCanvasPosition();
scale = canvasInstance.getScale();
const canvasContainer = canvasInstance.$el as HTMLElement;
if (canvasContainer) {
const viewportWidth = canvasContainer.clientWidth;
const viewportHeight = canvasContainer.clientHeight;
const canvasContainer = canvasInstance.$el as HTMLElement;
if (canvasContainer) {
const viewportWidth = canvasContainer.clientWidth;
const viewportHeight = canvasContainer.clientHeight;
position.x = (viewportWidth / 2 - position.x) / scale;
position.y = (viewportHeight / 2 - position.y) / scale;
}
position.x = (viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
position.y = (viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
}
} catch (error) {
console.error("获取画布位置时出错:", error);
@ -205,20 +301,16 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
const idPrefix = `template-${Date.now()}-`;
if (templateData.template?.parts) {
// 获取视口中心位置
// 使用内部管理的位置和缩放信息获取视口中心位置
let viewportCenter = { x: 300, y: 200 };
try {
if (canvasInstance.getCanvasPosition && canvasInstance.getScale) {
const position = canvasInstance.getCanvasPosition();
const scale = canvasInstance.getScale();
const canvasContainer = canvasInstance.$el as HTMLElement;
const canvasContainer = canvasInstance.$el as HTMLElement;
if (canvasContainer) {
const viewportWidth = canvasContainer.clientWidth;
const viewportHeight = canvasContainer.clientHeight;
viewportCenter.x = (viewportWidth / 2 - position.x) / scale;
viewportCenter.y = (viewportHeight / 2 - position.y) / scale;
}
if (canvasContainer) {
const viewportWidth = canvasContainer.clientWidth;
const viewportHeight = canvasContainer.clientHeight;
viewportCenter.x = (viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
viewportCenter.y = (viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
}
} catch (error) {
console.error("获取视口中心位置时出错:", error);
@ -527,29 +619,6 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
}
}
/**
*
*/
function getCanvasInfo() {
const canvasInstance = diagramCanvas.value;
if (!canvasInstance) return { position: { x: 0, y: 0 }, scale: 1 };
const position = canvasInstance.getCanvasPosition ? canvasInstance.getCanvasPosition() : { x: 0, y: 0 };
const scale = canvasInstance.getScale ? canvasInstance.getScale() : 1;
return { position, scale };
}
/**
*
*/
function showToast(message: string, type: "success" | "error" | "info" = "info") {
const canvasInstance = diagramCanvas.value;
if (canvasInstance && canvasInstance.showToast) {
canvasInstance.showToast(message, type);
}
}
/**
*
*/
@ -619,6 +688,10 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
selectedComponentConfig,
componentRefs,
// Canvas控制状态
canvasPosition,
canvasScale,
// 方法
loadComponentModule,
preloadComponentModules,
@ -634,11 +707,20 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
getComponentRef,
getDiagramData,
updateDiagramData,
getCanvasInfo,
showToast,
getComponentDefinition,
prepareComponentProps,
initialize,
// Canvas控制方法
setCanvasPosition,
updateCanvasPosition,
setCanvasScale,
getCanvasPosition,
getCanvasScale,
zoomAtPosition,
screenToCanvas,
canvasToScreen,
centerView,
};
}
);