mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
fix(core): support hover line or port in deep layer container (#443)
This commit is contained in:
parent
522bc0770d
commit
0a9c3a0167
@ -66,6 +66,8 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
|
||||
|
||||
private _hasError = false;
|
||||
|
||||
public stackIndex = 0;
|
||||
|
||||
/**
|
||||
* 线条数据
|
||||
*/
|
||||
|
||||
@ -7,7 +7,7 @@ import { last } from 'lodash-es';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { DisposableCollection, Emitter, type IPoint } from '@flowgram.ai/utils';
|
||||
import { FlowNodeRenderData, FlowNodeTransformData } from '@flowgram.ai/document';
|
||||
import { EntityManager, PlaygroundConfigEntity, TransformData } from '@flowgram.ai/core';
|
||||
import { EntityManager, PlaygroundConfigEntity } from '@flowgram.ai/core';
|
||||
|
||||
import { WorkflowDocumentOptions } from './workflow-document-option';
|
||||
import { type WorkflowDocument } from './workflow-document';
|
||||
@ -416,13 +416,8 @@ export class WorkflowLinesManager {
|
||||
.filter((port) => port.node.flowNodeType !== 'root');
|
||||
const targetPort = allPorts.find((port) => port.isHovered(pos.x, pos.y));
|
||||
if (targetPort) {
|
||||
// 后创建的要先校验
|
||||
const targetNode = this.document
|
||||
.getAllNodes()
|
||||
.slice()
|
||||
.reverse()
|
||||
.filter((node) => targetPort.node?.parent?.id !== node.id)
|
||||
.find((node) => node.getData(TransformData)!.contains(pos.x, pos.y));
|
||||
const containNodes = this.getContainNodesFromMousePos(pos);
|
||||
const targetNode = last(containNodes);
|
||||
// 点位可能会被节点覆盖
|
||||
if (targetNode && targetNode !== targetPort.node) {
|
||||
return;
|
||||
@ -436,27 +431,9 @@ export class WorkflowLinesManager {
|
||||
* @param pos - 鼠标位置
|
||||
*/
|
||||
getNodeFromMousePos(pos: IPoint): WorkflowNodeEntity | undefined {
|
||||
const allNodes = this.document
|
||||
.getAllNodes()
|
||||
.sort((a, b) => this.getNodeIndex(a) - this.getNodeIndex(b));
|
||||
// 先挑选出 bounds 区域符合的 node
|
||||
const containNodes: WorkflowNodeEntity[] = [];
|
||||
const { selection } = this.selectService;
|
||||
const zoom =
|
||||
this.entityManager.getEntity<PlaygroundConfigEntity>(PlaygroundConfigEntity)?.config?.zoom ||
|
||||
1;
|
||||
allNodes.forEach((node) => {
|
||||
const { bounds } = node.getData<FlowNodeTransformData>(FlowNodeTransformData);
|
||||
// 交互要求,节点边缘 4px 的时候就生效连线逻辑
|
||||
if (
|
||||
bounds
|
||||
.clone()
|
||||
.pad(4 / zoom)
|
||||
.contains(pos.x, pos.y)
|
||||
) {
|
||||
containNodes.push(node);
|
||||
}
|
||||
});
|
||||
const containNodes = this.getContainNodesFromMousePos(pos);
|
||||
// 当有元素被选中的时候选中元素在顶层
|
||||
if (selection?.length) {
|
||||
const filteredNodes = containNodes.filter((node) =>
|
||||
@ -479,6 +456,31 @@ export class WorkflowLinesManager {
|
||||
line.addData(WorkflowLineRenderData);
|
||||
}
|
||||
|
||||
/** 获取鼠标坐标位置的所有节点(stackIndex 从小到大排序) */
|
||||
private getContainNodesFromMousePos(pos: IPoint): WorkflowNodeEntity[] {
|
||||
const allNodes = this.document
|
||||
.getAllNodes()
|
||||
.sort((a, b) => this.getNodeIndex(a) - this.getNodeIndex(b));
|
||||
const zoom =
|
||||
this.entityManager.getEntity<PlaygroundConfigEntity>(PlaygroundConfigEntity)?.config?.zoom ||
|
||||
1;
|
||||
const containNodes = allNodes
|
||||
.map((node) => {
|
||||
const { bounds } = node.getData<FlowNodeTransformData>(FlowNodeTransformData);
|
||||
// 交互要求,节点边缘 4px 的时候就认为选中节点
|
||||
if (
|
||||
bounds
|
||||
.clone()
|
||||
.pad(4 / zoom)
|
||||
.contains(pos.x, pos.y)
|
||||
) {
|
||||
return node;
|
||||
}
|
||||
})
|
||||
.filter(Boolean) as WorkflowNodeEntity[];
|
||||
return containNodes;
|
||||
}
|
||||
|
||||
private getNodeIndex(node: WorkflowNodeEntity): number {
|
||||
const nodeRenderData = node.getData(FlowNodeRenderData);
|
||||
return nodeRenderData.stackIndex;
|
||||
|
||||
@ -236,38 +236,32 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
}
|
||||
}
|
||||
|
||||
const nodeInContainer = !!(nodeHovered?.parent && nodeHovered.parent.flowNodeType !== 'root');
|
||||
|
||||
// 获取最接近的线条
|
||||
// 线条会相交需要获取最接近点位的线条,不能删除的线条不能被选中
|
||||
const lineHovered = checkTargetFromLine
|
||||
? this.linesManager.getCloseInLineFromMousePos(mousePos)
|
||||
: undefined;
|
||||
const lineInContainer = !!lineHovered?.inContainer;
|
||||
|
||||
// 判断容器内节点是否 hover
|
||||
if (nodeHovered && nodeInContainer) {
|
||||
this.updateHoveredKey(nodeHovered.id);
|
||||
return;
|
||||
}
|
||||
// 判断容器内线条是否 hover
|
||||
if (lineHovered && lineInContainer) {
|
||||
this.updateHoveredKey(lineHovered.id);
|
||||
return;
|
||||
if (nodeHovered && lineHovered) {
|
||||
const nodeStackIndex = nodeHovered.renderData.stackIndex;
|
||||
const lineStackIndex = lineHovered.stackIndex;
|
||||
if (nodeStackIndex > lineStackIndex) {
|
||||
return this.updateHoveredKey(nodeHovered.id);
|
||||
} else {
|
||||
return this.updateHoveredKey(lineHovered.id);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断节点是否 hover
|
||||
if (nodeHovered) {
|
||||
this.updateHoveredKey(nodeHovered.id);
|
||||
return;
|
||||
return this.updateHoveredKey(nodeHovered.id);
|
||||
}
|
||||
// 判断线条是否 hover
|
||||
if (lineHovered) {
|
||||
this.hoverService.updateHoveredKey(lineHovered.id);
|
||||
return;
|
||||
return this.updateHoveredKey(lineHovered.id);
|
||||
}
|
||||
|
||||
// 上述逻辑都未命中 则清空 hoverd
|
||||
// 上述逻辑都未命中 则清空 hovered
|
||||
hoverService.clearHovered();
|
||||
|
||||
const currentState = this.editorStateConfig.getCurrentState();
|
||||
|
||||
@ -80,23 +80,26 @@ export class StackingContextManager {
|
||||
const element = nodeRenderData.node;
|
||||
element.style.position = 'absolute';
|
||||
if (level === undefined) {
|
||||
element.style.zIndex = 'auto';
|
||||
nodeRenderData.stackIndex = 0;
|
||||
element.style.zIndex = 'auto';
|
||||
return;
|
||||
}
|
||||
const stackIndex = StackingConfig.startIndex + level;
|
||||
element.style.zIndex = String(stackIndex);
|
||||
nodeRenderData.stackIndex = stackIndex;
|
||||
nodeRenderData.stackIndex = level;
|
||||
const zIndex = StackingConfig.startIndex + level;
|
||||
element.style.zIndex = String(zIndex);
|
||||
});
|
||||
this.lines.forEach((line) => {
|
||||
const level = lineLevel.get(line.id);
|
||||
const element = line.node;
|
||||
element.style.position = 'absolute';
|
||||
if (level === undefined) {
|
||||
line.stackIndex = 0;
|
||||
element.style.zIndex = 'auto';
|
||||
return;
|
||||
}
|
||||
element.style.zIndex = String(StackingConfig.startIndex + level);
|
||||
line.stackIndex = level;
|
||||
const zIndex = StackingConfig.startIndex + level;
|
||||
element.style.zIndex = String(zIndex);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user