group-node-register.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { IPoint, PaddingSchema, Point } from '@flowgram.ai/utils';
  6. import {
  7. FlowGroupController,
  8. FlowNodeBaseType,
  9. FlowNodeRegistry,
  10. FlowNodeTransformData,
  11. FlowTransitionLabelEnum,
  12. type FlowTransitionLine,
  13. FlowTransitionLineEnum,
  14. } from '@flowgram.ai/document';
  15. import { GroupRenderer, PositionConfig } from './constant';
  16. export const GroupRegister: FlowNodeRegistry = {
  17. type: FlowNodeBaseType.GROUP,
  18. meta: {
  19. exportJSON: true,
  20. renderKey: GroupRenderer.GroupRender,
  21. positionConfig: PositionConfig,
  22. padding: (transform: FlowNodeTransformData): PaddingSchema => {
  23. const groupController = FlowGroupController.create(transform.entity);
  24. if (!groupController || groupController.collapsed || groupController.nodes.length === 0) {
  25. return {
  26. top: 0,
  27. bottom: 0,
  28. left: 0,
  29. right: 0,
  30. };
  31. }
  32. if (transform.entity.isVertical) {
  33. return {
  34. top: PositionConfig.paddingWithNote,
  35. bottom: PositionConfig.paddingWithAddLabel,
  36. left: PositionConfig.padding,
  37. right: PositionConfig.padding,
  38. };
  39. }
  40. return {
  41. top: PositionConfig.paddingWithNote,
  42. bottom: PositionConfig.padding,
  43. left: PositionConfig.padding,
  44. right: PositionConfig.paddingWithAddLabel,
  45. };
  46. },
  47. },
  48. getLines(transition) {
  49. const { transform } = transition;
  50. const lines: FlowTransitionLine[] = [];
  51. if (transform.firstChild) {
  52. lines.push({
  53. type: FlowTransitionLineEnum.STRAIGHT_LINE,
  54. from: transform.inputPoint,
  55. to: transform.firstChild.inputPoint,
  56. });
  57. }
  58. if (transform.next) {
  59. lines.push({
  60. type: FlowTransitionLineEnum.STRAIGHT_LINE,
  61. from: transform.outputPoint,
  62. to: transform.next.inputPoint,
  63. });
  64. } else {
  65. lines.push({
  66. type: FlowTransitionLineEnum.STRAIGHT_LINE,
  67. from: transform.outputPoint,
  68. to: transform.parent!.outputPoint,
  69. });
  70. }
  71. return lines;
  72. },
  73. getDelta(transform: FlowNodeTransformData): IPoint | undefined {
  74. const groupController = FlowGroupController.create(transform.entity);
  75. if (!groupController || groupController.collapsed) {
  76. return;
  77. }
  78. if (transform.entity.isVertical) {
  79. return {
  80. x: 0,
  81. y: PositionConfig.paddingWithNote,
  82. };
  83. }
  84. return {
  85. x: PositionConfig.padding,
  86. y: 0,
  87. };
  88. },
  89. getInputPoint(transform: FlowNodeTransformData): IPoint {
  90. const child = transform.firstChild;
  91. if (!child) return transform.defaultInputPoint;
  92. if (transform.entity.isVertical) {
  93. return {
  94. x: child.inputPoint.x,
  95. y: transform.bounds.topCenter.y,
  96. };
  97. }
  98. return {
  99. x: transform.bounds.leftCenter.x,
  100. y: child.inputPoint.y,
  101. };
  102. },
  103. getOutputPoint(transform: FlowNodeTransformData): IPoint {
  104. const child = transform.lastChild;
  105. if (!child) return transform.defaultOutputPoint;
  106. if (transform.entity.isVertical) {
  107. return {
  108. x: child.outputPoint.x,
  109. y: child.outputPoint.y + PositionConfig.paddingWithAddLabel / 2,
  110. };
  111. }
  112. return {
  113. x: child.outputPoint.x + PositionConfig.paddingWithAddLabel / 2,
  114. y: child.outputPoint.y,
  115. };
  116. },
  117. getLabels(transition) {
  118. const { transform } = transition;
  119. if (transform.next) {
  120. if (transform.entity.isVertical) {
  121. return [
  122. {
  123. offset: Point.getMiddlePoint(
  124. Point.move(transform.outputPoint, {
  125. x: 0,
  126. y: PositionConfig.paddingWithAddLabel / 2,
  127. }),
  128. transform.next.inputPoint
  129. ),
  130. type: FlowTransitionLabelEnum.ADDER_LABEL,
  131. },
  132. ];
  133. }
  134. return [
  135. {
  136. offset: Point.getMiddlePoint(
  137. Point.move(transform.outputPoint, { x: PositionConfig.paddingWithAddLabel / 2, y: 0 }),
  138. transform.next.inputPoint
  139. ),
  140. type: FlowTransitionLabelEnum.ADDER_LABEL,
  141. },
  142. ];
  143. }
  144. return [
  145. {
  146. offset: transform.parent!.outputPoint,
  147. type: FlowTransitionLabelEnum.ADDER_LABEL,
  148. },
  149. ];
  150. },
  151. getOriginDeltaY(transform): number {
  152. const { children } = transform;
  153. if (children.length === 0) {
  154. return -transform.size.height * transform.origin.y;
  155. }
  156. // 这里要加上 y 轴的偏移
  157. return -transform.size.height * transform.origin.y - PositionConfig.paddingWithNote;
  158. },
  159. };