Explorar o código

fix(canvas-core): cache the node stack index in node render data

liuyangxing hai 10 meses
pai
achega
7d40e92e5f

+ 10 - 0
packages/canvas-engine/document/src/datas/flow-node-render-data.ts

@@ -13,6 +13,7 @@ export interface FlowNodeRenderSchema {
   activated: boolean; // 是否高亮节点
   hovered: boolean; // 是否悬浮在节点上
   dragging: boolean; // 是否正在拖拽
+  stackIndex: number; // 渲染层级
   extInfo?: Record<string, any>; // 扩展渲染状态字段
 }
 
@@ -43,6 +44,7 @@ export class FlowNodeRenderData extends EntityData<FlowNodeRenderSchema> {
       activated: false,
       hovered: false,
       dragging: false,
+      stackIndex: 0,
     };
   }
 
@@ -183,6 +185,14 @@ export class FlowNodeRenderData extends EntityData<FlowNodeRenderSchema> {
     return this.data.activated;
   }
 
+  get stackIndex(): number {
+    return this.data.stackIndex;
+  }
+
+  set stackIndex(index: number) {
+    this.data.stackIndex = index;
+  }
+
   get lineActivated() {
     const { activated } = this;
     if (!activated) return false;

+ 9 - 2
packages/canvas-engine/free-layout-core/src/workflow-lines-manager.ts

@@ -1,7 +1,7 @@
 import { last } from 'lodash-es';
 import { inject, injectable } from 'inversify';
 import { Disposable, DisposableCollection, Emitter, type IPoint } from '@flowgram.ai/utils';
-import { FlowNodeTransformData } from '@flowgram.ai/document';
+import { FlowNodeRenderData, FlowNodeTransformData } from '@flowgram.ai/document';
 import { EntityManager, PlaygroundConfigEntity, TransformData } from '@flowgram.ai/core';
 
 import { WorkflowDocumentOptions } from './workflow-document-option';
@@ -428,7 +428,9 @@ export class WorkflowLinesManager {
    * @param pos - 鼠标位置
    */
   getNodeFromMousePos(pos: IPoint): WorkflowNodeEntity | undefined {
-    const allNodes = this.document.getAllNodes();
+    const allNodes = this.document
+      .getAllNodes()
+      .sort((a, b) => this.getNodeIndex(a) - this.getNodeIndex(b));
     // 先挑选出 bounds 区域符合的 node
     const containNodes: WorkflowNodeEntity[] = [];
     const { selection } = this.selectService;
@@ -468,4 +470,9 @@ export class WorkflowLinesManager {
   private registerData(line: WorkflowLineEntity) {
     line.addData(WorkflowLineRenderData);
   }
+
+  private getNodeIndex(node: WorkflowNodeEntity): number {
+    const nodeRenderData = node.getData(FlowNodeRenderData);
+    return nodeRenderData.stackIndex;
+  }
 }

+ 13 - 10
packages/plugins/free-stack-plugin/src/manager.ts

@@ -1,7 +1,7 @@
 import { debounce } from 'lodash';
 import { inject, injectable } from 'inversify';
-import { FlowNodeRenderData } from '@flowgram.ai/document';
-import { EntityManager, PipelineRegistry, PipelineRenderer } from '@flowgram.ai/core';
+import { domUtils } from '@flowgram.ai/utils';
+import { Disposable } from '@flowgram.ai/utils';
 import {
   WorkflowHoverService,
   WorkflowNodeEntity,
@@ -9,8 +9,8 @@ import {
 } from '@flowgram.ai/free-layout-core';
 import { WorkflowLineEntity } from '@flowgram.ai/free-layout-core';
 import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
-import { domUtils } from '@flowgram.ai/utils';
-import { Disposable } from '@flowgram.ai/utils';
+import { FlowNodeRenderData } from '@flowgram.ai/document';
+import { EntityManager, PipelineRegistry, PipelineRenderer } from '@flowgram.ai/core';
 
 import type { StackingContext } from './type';
 import { StackingComputing } from './stacking-computing';
@@ -36,7 +36,7 @@ export class StackingContextManager {
   private readonly selectService: WorkflowSelectService;
 
   public readonly node = domUtils.createDivWithClass(
-    'gedit-playground-layer gedit-flow-render-layer',
+    'gedit-playground-layer gedit-flow-render-layer'
   );
 
   private disposers: Disposable[] = [];
@@ -56,7 +56,7 @@ export class StackingContextManager {
   }
 
   public dispose(): void {
-    this.disposers.forEach(disposer => disposer.dispose());
+    this.disposers.forEach((disposer) => disposer.dispose());
   }
 
   /**
@@ -85,18 +85,21 @@ export class StackingContextManager {
       nodes: this.nodes,
       context,
     });
-    this.nodes.forEach(node => {
+    this.nodes.forEach((node) => {
       const level = nodeLevel.get(node.id);
       const nodeRenderData = node.getData<FlowNodeRenderData>(FlowNodeRenderData);
       const element = nodeRenderData.node;
       element.style.position = 'absolute';
       if (!level) {
         element.style.zIndex = 'auto';
+        nodeRenderData.stackIndex = 0;
         return;
       }
-      element.style.zIndex = String(StackingConfig.startIndex + level);
+      const stackIndex = StackingConfig.startIndex + level;
+      element.style.zIndex = String(stackIndex);
+      nodeRenderData.stackIndex = stackIndex;
     });
-    this.lines.forEach(line => {
+    this.lines.forEach((line) => {
       const level = lineLevel.get(line.id);
       const element = line.node;
       element.style.position = 'absolute';
@@ -121,7 +124,7 @@ export class StackingContextManager {
       hoveredEntity: this.hoverService.hoveredNode,
       hoveredEntityID: this.hoverService.hoveredNode?.id,
       selectedEntities: this.selectService.selection,
-      selectedIDs: this.selectService.selection.map(entity => entity.id),
+      selectedIDs: this.selectService.selection.map((entity) => entity.id),
     };
   }