feat:减少冗余代码???

This commit is contained in:
2025-07-13 14:48:18 +08:00
parent f710a66c69
commit a76ee74656
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;
// 使用requestAnimationFrame确保UI更新
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;