@flowgram.ai/free-lines-plugin 0.1.21 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1268,6 +1268,7 @@ WorkflowManhattanLineContribution.type = "WorkflowManhattanLineContribution";
1268
1268
 
1269
1269
  // src/create-free-lines-plugin.ts
1270
1270
  var createFreeLinesPlugin = definePluginCreator({
1271
+ singleton: true,
1271
1272
  onInit: (ctx, opts) => {
1272
1273
  ctx.playground.registerLayer(WorkflowLinesLayer, {
1273
1274
  ...opts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/workflow-port-render/index.tsx","../../src/constants/points.ts","../../src/components/workflow-port-render/style.ts","../../src/components/workflow-port-render/cross-hair.tsx","../../src/constants/lines.ts","../../src/create-free-lines-plugin.ts","../../src/layer/workflow-lines-layer.tsx","../../src/components/workflow-line-render/index.tsx","../../src/components/workflow-line-render/line-svg.tsx","../../src/components/workflow-line-render/index.style.ts","../../src/components/workflow-line-render/arrow.tsx","../../src/contributions/bezier/bezier-controls.ts","../../src/contributions/bezier/index.ts","../../src/contributions/fold/index.ts","../../src/contributions/fold/fold-line.ts","../../src/contributions/straight/index.ts","../../src/contributions/straight/point-on-line.ts","../../src/contributions/arc/index.ts","../../src/contributions/manhattan/index.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点和直线的距离\n * @param p1\n * @param p2\n * @param p3\n */\nfunction pointLineDistance(p1: IPoint, p2: IPoint, p3: IPoint): number {\n let len;\n\n // 竖着的线\n if (p1.x - p2.x === 0) {\n len = Math.abs(p3.x - p1.x);\n } else {\n const A = (p1.y - p2.y) / (p1.x - p2.x);\n const B = p1.y - A * p1.x;\n\n len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));\n }\n\n return len;\n}\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 折叠线和点的距离\n * @param linePosition\n * @param pos\n */\n export function getFoldLineToPointDistance(points: IPoint[], pos: IPoint): number {\n const bounds = getBounds(points);\n if (bounds.contains(pos.x, pos.y)) {\n const lines = points.reduce((res, point, index) => {\n if (index === 0) {\n return res;\n }\n res.push([points[index - 1]!, point]);\n return res;\n }, [] as [IPoint, IPoint][]);\n return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));\n }\n return Math.min(...points.map((p) => Point.getDistance(p, pos)));\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["React","React","WorkflowLinesManager","ReactDOM","React","useState","WorkflowHoverService","WorkflowLineRenderData","React","styled","React","React","React","useState","WorkflowLineRenderData","React","ReactDOM","WorkflowHoverService","BezierControlType","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","FoldLine","xDir","yDir","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","WorkflowLinesManager"]}
1
+ {"version":3,"sources":["../../src/components/workflow-port-render/index.tsx","../../src/constants/points.ts","../../src/components/workflow-port-render/style.ts","../../src/components/workflow-port-render/cross-hair.tsx","../../src/constants/lines.ts","../../src/create-free-lines-plugin.ts","../../src/layer/workflow-lines-layer.tsx","../../src/components/workflow-line-render/index.tsx","../../src/components/workflow-line-render/line-svg.tsx","../../src/components/workflow-line-render/index.style.ts","../../src/components/workflow-line-render/arrow.tsx","../../src/contributions/bezier/bezier-controls.ts","../../src/contributions/bezier/index.ts","../../src/contributions/fold/index.ts","../../src/contributions/fold/fold-line.ts","../../src/contributions/straight/index.ts","../../src/contributions/straight/point-on-line.ts","../../src/contributions/arc/index.ts","../../src/contributions/manhattan/index.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点和直线的距离\n * @param p1\n * @param p2\n * @param p3\n */\nfunction pointLineDistance(p1: IPoint, p2: IPoint, p3: IPoint): number {\n let len;\n\n // 竖着的线\n if (p1.x - p2.x === 0) {\n len = Math.abs(p3.x - p1.x);\n } else {\n const A = (p1.y - p2.y) / (p1.x - p2.x);\n const B = p1.y - A * p1.x;\n\n len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));\n }\n\n return len;\n}\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 折叠线和点的距离\n * @param linePosition\n * @param pos\n */\n export function getFoldLineToPointDistance(points: IPoint[], pos: IPoint): number {\n const bounds = getBounds(points);\n if (bounds.contains(pos.x, pos.y)) {\n const lines = points.reduce((res, point, index) => {\n if (index === 0) {\n return res;\n }\n res.push([points[index - 1]!, point]);\n return res;\n }, [] as [IPoint, IPoint][]);\n return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));\n }\n return Math.min(...points.map((p) => Point.getDistance(p, pos)));\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["React","React","WorkflowLinesManager","ReactDOM","React","useState","WorkflowHoverService","WorkflowLineRenderData","React","styled","React","React","React","useState","WorkflowLineRenderData","React","ReactDOM","WorkflowHoverService","BezierControlType","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","FoldLine","xDir","yDir","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","WorkflowLinesManager"]}
package/dist/index.js CHANGED
@@ -1291,6 +1291,7 @@ WorkflowManhattanLineContribution.type = "WorkflowManhattanLineContribution";
1291
1291
 
1292
1292
  // src/create-free-lines-plugin.ts
1293
1293
  var createFreeLinesPlugin = (0, import_core3.definePluginCreator)({
1294
+ singleton: true,
1294
1295
  onInit: (ctx, opts) => {
1295
1296
  ctx.playground.registerLayer(WorkflowLinesLayer, {
1296
1297
  ...opts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/workflow-port-render/index.tsx","../src/constants/points.ts","../src/components/workflow-port-render/style.ts","../src/components/workflow-port-render/cross-hair.tsx","../src/constants/lines.ts","../src/create-free-lines-plugin.ts","../src/layer/workflow-lines-layer.tsx","../src/components/workflow-line-render/index.tsx","../src/components/workflow-line-render/line-svg.tsx","../src/components/workflow-line-render/index.style.ts","../src/components/workflow-line-render/arrow.tsx","../src/contributions/bezier/bezier-controls.ts","../src/contributions/bezier/index.ts","../src/contributions/fold/index.ts","../src/contributions/fold/fold-line.ts","../src/contributions/straight/index.ts","../src/contributions/straight/point-on-line.ts","../src/contributions/arc/index.ts","../src/contributions/manhattan/index.ts"],"sourcesContent":["export * from './components/workflow-port-render';\nexport * from './constants/lines';\nexport * from './create-free-lines-plugin';\nexport * from './layer';\nexport * from './type';\nexport * from './contributions';\n","import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点和直线的距离\n * @param p1\n * @param p2\n * @param p3\n */\nfunction pointLineDistance(p1: IPoint, p2: IPoint, p3: IPoint): number {\n let len;\n\n // 竖着的线\n if (p1.x - p2.x === 0) {\n len = Math.abs(p3.x - p1.x);\n } else {\n const A = (p1.y - p2.y) / (p1.x - p2.x);\n const B = p1.y - A * p1.x;\n\n len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));\n }\n\n return len;\n}\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 折叠线和点的距离\n * @param linePosition\n * @param pos\n */\n export function getFoldLineToPointDistance(points: IPoint[], pos: IPoint): number {\n const bounds = getBounds(points);\n if (bounds.contains(pos.x, pos.y)) {\n const lines = points.reduce((res, point, index) => {\n if (index === 0) {\n return res;\n }\n res.push([points[index - 1]!, point]);\n return res;\n }, [] as [IPoint, IPoint][]);\n return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));\n }\n return Math.min(...points.map((p) => Point.getDistance(p, pos)));\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["import_react","styled","React","React","classNames","ReactDOM","import_free_layout_core","import_core","import_react_dom","import_react","import_free_layout_core","import_core","import_react","import_react","import_clsx","import_free_layout_core","import_styled_components","styled","import_react","React","React","clsx","React","ReactDOM","import_utils","BezierControlType","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","FoldLine","xDir","yDir","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","import_free_layout_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/workflow-port-render/index.tsx","../src/constants/points.ts","../src/components/workflow-port-render/style.ts","../src/components/workflow-port-render/cross-hair.tsx","../src/constants/lines.ts","../src/create-free-lines-plugin.ts","../src/layer/workflow-lines-layer.tsx","../src/components/workflow-line-render/index.tsx","../src/components/workflow-line-render/line-svg.tsx","../src/components/workflow-line-render/index.style.ts","../src/components/workflow-line-render/arrow.tsx","../src/contributions/bezier/bezier-controls.ts","../src/contributions/bezier/index.ts","../src/contributions/fold/index.ts","../src/contributions/fold/fold-line.ts","../src/contributions/straight/index.ts","../src/contributions/straight/point-on-line.ts","../src/contributions/arc/index.ts","../src/contributions/manhattan/index.ts"],"sourcesContent":["export * from './components/workflow-port-render';\nexport * from './constants/lines';\nexport * from './create-free-lines-plugin';\nexport * from './layer';\nexport * from './type';\nexport * from './contributions';\n","import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点和直线的距离\n * @param p1\n * @param p2\n * @param p3\n */\nfunction pointLineDistance(p1: IPoint, p2: IPoint, p3: IPoint): number {\n let len;\n\n // 竖着的线\n if (p1.x - p2.x === 0) {\n len = Math.abs(p3.x - p1.x);\n } else {\n const A = (p1.y - p2.y) / (p1.x - p2.x);\n const B = p1.y - A * p1.x;\n\n len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));\n }\n\n return len;\n}\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 折叠线和点的距离\n * @param linePosition\n * @param pos\n */\n export function getFoldLineToPointDistance(points: IPoint[], pos: IPoint): number {\n const bounds = getBounds(points);\n if (bounds.contains(pos.x, pos.y)) {\n const lines = points.reduce((res, point, index) => {\n if (index === 0) {\n return res;\n }\n res.push([points[index - 1]!, point]);\n return res;\n }, [] as [IPoint, IPoint][]);\n return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));\n }\n return Math.min(...points.map((p) => Point.getDistance(p, pos)));\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["import_react","styled","React","React","classNames","ReactDOM","import_free_layout_core","import_core","import_react_dom","import_react","import_free_layout_core","import_core","import_react","import_react","import_clsx","import_free_layout_core","import_styled_components","styled","import_react","React","React","clsx","React","ReactDOM","import_utils","BezierControlType","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","FoldLine","xDir","yDir","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","import_free_layout_core"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/free-lines-plugin",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -20,11 +20,11 @@
20
20
  "clsx": "^1.1.1",
21
21
  "inversify": "^6.0.1",
22
22
  "reflect-metadata": "~0.2.2",
23
- "@flowgram.ai/free-layout-core": "0.1.21",
24
- "@flowgram.ai/core": "0.1.21",
25
- "@flowgram.ai/free-stack-plugin": "0.1.21",
26
- "@flowgram.ai/utils": "0.1.21",
27
- "@flowgram.ai/renderer": "0.1.21"
23
+ "@flowgram.ai/core": "0.1.23",
24
+ "@flowgram.ai/free-stack-plugin": "0.1.23",
25
+ "@flowgram.ai/renderer": "0.1.23",
26
+ "@flowgram.ai/utils": "0.1.23",
27
+ "@flowgram.ai/free-layout-core": "0.1.23"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/bezier-js": "4.1.3",
@@ -40,8 +40,8 @@
40
40
  "tsup": "^8.0.1",
41
41
  "typescript": "^5.0.4",
42
42
  "vitest": "^0.34.6",
43
- "@flowgram.ai/eslint-config": "0.1.21",
44
- "@flowgram.ai/ts-config": "0.1.21"
43
+ "@flowgram.ai/eslint-config": "0.1.23",
44
+ "@flowgram.ai/ts-config": "0.1.23"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": ">=17",