@flowgram.ai/free-lines-plugin 0.1.0-alpha.12 → 0.1.0-alpha.13

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.
@@ -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":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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 { MouseTouchEvent, 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?: (e: React.MouseEvent<HTMLDivElement>, port: WorkflowPortEntity) => void;\n /** 激活状态颜色 (linked/hovered) */\n primaryColor?: string;\n /** 默认状态颜色 */\n secondaryColor?: string;\n /** 错误状态颜色 */\n errorColor?: string;\n /** 背景颜色 */\n backgroundColor?: string;\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('workflow-port-render', props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n\n // 构建 CSS 自定义属性用于颜色覆盖\n const colorStyles: Record<string, string> = {};\n if (props.primaryColor) {\n colorStyles['--g-workflow-port-color-primary'] = props.primaryColor;\n }\n if (props.secondaryColor) {\n colorStyles['--g-workflow-port-color-secondary'] = props.secondaryColor;\n }\n if (props.errorColor) {\n colorStyles['--g-workflow-port-color-error'] = props.errorColor;\n }\n if (props.backgroundColor) {\n colorStyles['--g-workflow-port-color-background'] = props.backgroundColor;\n }\n\n const combinedStyle = targetElement\n ? { ...props.style, ...colorStyles }\n : { ...props.style, ...colorStyles, left: posX, top: posY };\n\n const content = (\n <WorkflowPointStyle\n className={className}\n style={combinedStyle}\n onClick={(e) => onClick?.(e, entity)}\n onTouchStart={(e) => {\n if (!onClick) {\n return;\n }\n MouseTouchEvent.onTouched(e, (mouseEvent) => {\n onClick(mouseEvent as unknown as React.MouseEvent<HTMLDivElement>, entity);\n });\n }}\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 * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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: var(--g-workflow-port-color-background, #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: var(--g-workflow-port-color-secondary, #9197f1);\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: var(--g-workflow-port-color-error, red);\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: var(--g-workflow-port-color-background, #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: var(--g-workflow-port-color-secondary, #9197f1);\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: var(--g-workflow-port-color-primary, #4d53e8);\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: var(--g-workflow-port-color-primary, #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: var(--g-workflow-port-color-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 var(--g-workflow-port-color-background, #fff);\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { FlowRendererRegistry } from '@flowgram.ai/renderer';\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 @inject(FlowRendererRegistry) rendererRegistry: FlowRendererRegistry;\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 { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const version = this.lineVersion(line);\n\n return {\n key: line.id,\n color: line.color,\n selected,\n hovered,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n rendererRegistry: this.rendererRegistry,\n };\n }\n\n private lineVersion(line: WorkflowLineEntity): string {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${\n selected ? 'T' : 'F'\n },h:${hovered ? 'T' : 'F'}`;\n\n return version;\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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 { type ArrowRendererComponent } from '../../types/arrow-renderer';\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, rendererRegistry } = 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 // 获取自定义箭头渲染器,如果没有则使用默认的\n const CustomArrowRenderer = rendererRegistry?.tryToGetRendererComponent('arrow-renderer')\n ?.renderer as ArrowRendererComponent;\n const ArrowComponent = CustomArrowRenderer || ArrowRenderer;\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 <ArrowComponent\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n line={line}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { type ArrowRendererProps } from '../../types/arrow-renderer';\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: ArrowRendererProps) {\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport {\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\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 points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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/index.ts","../../src/contributions/bezier/bezier-controls.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"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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 { MouseTouchEvent, 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?: (e: React.MouseEvent<HTMLDivElement>, port: WorkflowPortEntity) => void;\n /** 激活状态颜色 (linked/hovered) */\n primaryColor?: string;\n /** 默认状态颜色 */\n secondaryColor?: string;\n /** 错误状态颜色 */\n errorColor?: string;\n /** 背景颜色 */\n backgroundColor?: string;\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('workflow-port-render', props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n\n // 构建 CSS 自定义属性用于颜色覆盖\n const colorStyles: Record<string, string> = {};\n if (props.primaryColor) {\n colorStyles['--g-workflow-port-color-primary'] = props.primaryColor;\n }\n if (props.secondaryColor) {\n colorStyles['--g-workflow-port-color-secondary'] = props.secondaryColor;\n }\n if (props.errorColor) {\n colorStyles['--g-workflow-port-color-error'] = props.errorColor;\n }\n if (props.backgroundColor) {\n colorStyles['--g-workflow-port-color-background'] = props.backgroundColor;\n }\n\n const combinedStyle = targetElement\n ? { ...props.style, ...colorStyles }\n : { ...props.style, ...colorStyles, left: posX, top: posY };\n\n const content = (\n <WorkflowPointStyle\n className={className}\n style={combinedStyle}\n onClick={(e) => onClick?.(e, entity)}\n onTouchStart={(e) => {\n if (!onClick) {\n return;\n }\n MouseTouchEvent.onTouched(e, (mouseEvent) => {\n onClick(mouseEvent as unknown as React.MouseEvent<HTMLDivElement>, entity);\n });\n }}\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 * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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: var(--g-workflow-port-color-background, #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: var(--g-workflow-port-color-secondary, #9197f1);\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: var(--g-workflow-port-color-error, red);\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: var(--g-workflow-port-color-background, #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: var(--g-workflow-port-color-secondary, #9197f1);\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: var(--g-workflow-port-color-primary, #4d53e8);\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: var(--g-workflow-port-color-primary, #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: var(--g-workflow-port-color-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 var(--g-workflow-port-color-background, #fff);\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { FlowRendererRegistry } from '@flowgram.ai/renderer';\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 @inject(FlowRendererRegistry) rendererRegistry: FlowRendererRegistry;\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 { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const version = this.lineVersion(line);\n\n return {\n key: line.id,\n color: line.color,\n selected,\n hovered,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n rendererRegistry: this.rendererRegistry,\n };\n }\n\n private lineVersion(line: WorkflowLineEntity): string {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${\n selected ? 'T' : 'F'\n },h:${hovered ? 'T' : 'F'}`;\n\n return version;\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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 { type ArrowRendererComponent } from '../../types/arrow-renderer';\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\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix, rendererRegistry } = props;\n const { position, reverse, hideArrow, vertical } = 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 =\n position.to.location === 'top'\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint =\n position.from.location === 'bottom'\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\n ? line.uiState.strokeWidthSelected ?? STROKE_WIDTH_SLECTED\n : line.uiState.strokeWidth ?? STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n // 获取自定义箭头渲染器,如果没有则使用默认的\n const CustomArrowRenderer = rendererRegistry?.tryToGetRendererComponent('arrow-renderer')\n ?.renderer as ArrowRendererComponent;\n const ArrowComponent = CustomArrowRenderer || ArrowRenderer;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n style={line.uiState.style}\n className={clsx(\n line.className,\n 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 <ArrowComponent\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n line={line}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { type ArrowRendererProps } from '../../types/arrow-renderer';\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: ArrowRendererProps) {\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n LinePoint,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { getBezierControlPoints } 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: LinePoint; toPos: LinePoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: LinePoint, toPos: LinePoint): BezierData {\n const controls = getBezierControlPoints(fromPos, toPos, this.entity.uiState.curvature);\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: LinePoint;\n toPos: LinePoint;\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 const shrink = this.entity.uiState.shrink;\n\n const renderFromPos: IPoint =\n params.fromPos.location === 'bottom'\n ? { x: fromPos.x, y: fromPos.y + shrink }\n : { x: fromPos.x + shrink, y: fromPos.y };\n\n const renderToPos: IPoint =\n params.toPos.location === 'top'\n ? { x: toPos.x, y: toPos.y - shrink }\n : { x: toPos.x - shrink, y: toPos.y };\n\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n return `M${renderFromPos.x} ${renderFromPos.y} C ${controlPoints}, ${renderToPos.x} ${renderToPos.y}`;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { LinePoint, LinePointLocation } from '@flowgram.ai/free-layout-core';\n\nfunction getControlOffset(distance: number, curvature: number): number {\n if (distance >= 0) {\n return 0.5 * distance;\n }\n\n return curvature * 25 * Math.sqrt(-distance);\n}\n\nfunction getControlWithCurvature({\n location,\n x1,\n y1,\n x2,\n y2,\n curvature,\n}: {\n location: LinePointLocation;\n curvature: number;\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}): IPoint {\n switch (location) {\n case 'left':\n return {\n x: x1 - getControlOffset(x1 - x2, curvature),\n y: y1,\n };\n case 'right':\n return {\n x: x1 + getControlOffset(x2 - x1, curvature),\n y: y1,\n };\n case 'top':\n return {\n x: x1,\n y: y1 - getControlOffset(y1 - y2, curvature),\n };\n case 'bottom':\n return {\n x: x1,\n y: y1 + getControlOffset(y2 - y1, curvature),\n };\n }\n}\n\nexport function getBezierControlPoints(\n fromPos: LinePoint,\n toPos: LinePoint,\n curvature = 0.25\n): IPoint[] {\n const fromControl = getControlWithCurvature({\n location: fromPos.location,\n x1: fromPos.x,\n y1: fromPos.y,\n x2: toPos.x,\n y2: toPos.y,\n curvature,\n });\n const toControl = getControlWithCurvature({\n location: toPos.location,\n x1: toPos.x,\n y1: toPos.y,\n x2: fromPos.x,\n y2: fromPos.y,\n curvature,\n });\n return [fromControl, toControl];\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n LinePoint,\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: LinePoint; toPos: LinePoint }): void {\n const { fromPos, toPos } = params;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: fromPos.location === 'bottom' ? 0 : POINT_RADIUS,\n y: fromPos.location === 'bottom' ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: toPos.location === 'top' ? 0 : -POINT_RADIUS,\n y: toPos.location === 'top' ? -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 location: fromPos.location,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n location: toPos.location,\n },\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport { LinePoint } from '@flowgram.ai/free-layout-core';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\n};\n\n/**\n * Fork from: https://github.com/xyflow/xyflow/blob/main/packages/system/src/utils/edges/smoothstep-edge.ts\n * MIT License\n * Copyright (c) 2019-2024 webkid GmbH\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: LinePoint; target: LinePoint }): IPoint => {\n if (source.location === 'left' || source.location === 'right') {\n return source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n }\n return source.y < target.y ? { x: 0, y: 1 } : { x: 0, y: -1 };\n };\n\n const handleDirections = {\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n top: { x: 0, y: -1 },\n bottom: { x: 0, y: 1 },\n };\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n }: {\n source: LinePoint;\n target: LinePoint;\n }): IPoint[] {\n const sourceDir = handleDirections[source.location];\n const targetDir = handleDirections[target.location];\n const sourceGapped: LinePoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n location: source.location,\n };\n const targetGapped: LinePoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n location: target.location,\n };\n const dir = getDirection({\n source: sourceGapped,\n target: targetGapped,\n });\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 points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n LinePoint,\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: LinePoint; toPos: LinePoint }): void {\n const { fromPos, toPos } = params;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: fromPos.location === 'bottom' ? 0 : POINT_RADIUS,\n y: fromPos.location === 'bottom' ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: toPos.location === 'top' ? 0 : -POINT_RADIUS,\n y: toPos.location === 'top' ? -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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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"],"mappings":"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","names":["React","React","WorkflowLinesManager","ReactDOM","React","useState","WorkflowHoverService","WorkflowLineRenderData","React","styled","React","React","React","useState","WorkflowLineRenderData","React","ReactDOM","WorkflowHoverService","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","WorkflowLinesManager"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode, FC } from 'react';
2
- import { WorkflowPortEntity, WorkflowLineEntity, LineRenderType, WorkflowLineRenderContributionFactory, WorkflowHoverService, WorkflowSelectService, WorkflowDocument, WorkflowLineRenderContribution, LineType } from '@flowgram.ai/free-layout-core';
2
+ import { WorkflowPortEntity, WorkflowLineEntity, LineRenderType, WorkflowLineRenderContributionFactory, WorkflowHoverService, WorkflowSelectService, WorkflowDocument, WorkflowLineRenderContribution, LineType, LinePoint } from '@flowgram.ai/free-layout-core';
3
3
  import * as _flowgram_ai_core from '@flowgram.ai/core';
4
4
  import { Layer, TransformData } from '@flowgram.ai/core';
5
5
  import { FlowRendererRegistry } from '@flowgram.ai/renderer';
@@ -125,30 +125,6 @@ interface ArrowRendererProps {
125
125
  */
126
126
  type ArrowRendererComponent = React.ComponentType<ArrowRendererProps>;
127
127
 
128
- /**
129
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
130
- * SPDX-License-Identifier: MIT
131
- */
132
-
133
- declare enum BezierControlType {
134
- RIGHT_TOP = 0,
135
- RIGHT_BOTTOM = 1,
136
- LEFT_TOP = 2,
137
- LEFT_BOTTOM = 3
138
- }
139
- /**
140
- * 获取贝塞尔曲线横向的控制节点
141
- * @param fromPos
142
- * @param toPos
143
- */
144
- declare function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[];
145
- /**
146
- * 获取贝塞尔曲线垂直方向的控制节点
147
- * @param fromPos 起始点
148
- * @param toPos 终点
149
- */
150
- declare function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[];
151
-
152
128
  /**
153
129
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
154
130
  * SPDX-License-Identifier: MIT
@@ -171,8 +147,8 @@ declare class WorkflowBezierLineContribution implements WorkflowLineRenderContri
171
147
  calcDistance(pos: IPoint): number;
172
148
  get bounds(): Rectangle;
173
149
  update(params: {
174
- fromPos: IPoint;
175
- toPos: IPoint;
150
+ fromPos: LinePoint;
151
+ toPos: LinePoint;
176
152
  }): void;
177
153
  private calcBezier;
178
154
  private getPath;
@@ -197,8 +173,8 @@ declare class WorkflowFoldLineContribution implements WorkflowLineRenderContribu
197
173
  calcDistance(pos: IPoint): number;
198
174
  get bounds(): Rectangle;
199
175
  update(params: {
200
- fromPos: IPoint;
201
- toPos: IPoint;
176
+ fromPos: LinePoint;
177
+ toPos: LinePoint;
202
178
  }): void;
203
179
  }
204
180
 
@@ -221,8 +197,8 @@ declare class WorkflowStraightLineContribution implements WorkflowLineRenderCont
221
197
  calcDistance(pos: IPoint): number;
222
198
  get bounds(): Rectangle;
223
199
  update(params: {
224
- fromPos: IPoint;
225
- toPos: IPoint;
200
+ fromPos: LinePoint;
201
+ toPos: LinePoint;
226
202
  }): void;
227
203
  }
228
204
 
@@ -253,31 +229,4 @@ declare class WorkflowArkLineContribution implements WorkflowLineRenderContribut
253
229
  private getArcPath;
254
230
  }
255
231
 
256
- /**
257
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
258
- * SPDX-License-Identifier: MIT
259
- */
260
-
261
- interface ManhattanData {
262
- points: IPoint[];
263
- path: string;
264
- bbox: Rectangle;
265
- }
266
- declare class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {
267
- static type: string;
268
- entity: WorkflowLineEntity;
269
- constructor(entity: WorkflowLineEntity);
270
- private data?;
271
- get path(): string;
272
- calcDistance(pos: IPoint): number;
273
- private getDistanceToLineSegment;
274
- get bounds(): Rectangle;
275
- update(params: {
276
- fromPos: IPoint;
277
- toPos: IPoint;
278
- }): void;
279
- private getManhattanPoints;
280
- private getPathFromPoints;
281
- }
282
-
283
- export { type ArcData, type ArrowRendererComponent, type ArrowRendererProps, BezierControlType, type BezierData, type FoldData, type FreeLinesPluginOptions, LINE_OFFSET, LINE_PADDING, type LineRenderProps, WorkflowLinesLayer as LinesLayer, type LinesLayerOptions, type ManhattanData, type StraightData, WorkflowArkLineContribution, WorkflowBezierLineContribution, WorkflowFoldLineContribution, WorkflowLinesLayer, WorkflowManhattanLineContribution, WorkflowPortRender, type WorkflowPortRenderProps, WorkflowStraightLineContribution, createFreeLinesPlugin, getBezierHorizontalControlPoints, getBezierVerticalControlPoints };
232
+ export { type ArcData, type ArrowRendererComponent, type ArrowRendererProps, type BezierData, type FoldData, type FreeLinesPluginOptions, LINE_OFFSET, LINE_PADDING, type LineRenderProps, WorkflowLinesLayer as LinesLayer, type LinesLayerOptions, type StraightData, WorkflowArkLineContribution, WorkflowBezierLineContribution, WorkflowFoldLineContribution, WorkflowLinesLayer, WorkflowPortRender, type WorkflowPortRenderProps, WorkflowStraightLineContribution, createFreeLinesPlugin };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode, FC } from 'react';
2
- import { WorkflowPortEntity, WorkflowLineEntity, LineRenderType, WorkflowLineRenderContributionFactory, WorkflowHoverService, WorkflowSelectService, WorkflowDocument, WorkflowLineRenderContribution, LineType } from '@flowgram.ai/free-layout-core';
2
+ import { WorkflowPortEntity, WorkflowLineEntity, LineRenderType, WorkflowLineRenderContributionFactory, WorkflowHoverService, WorkflowSelectService, WorkflowDocument, WorkflowLineRenderContribution, LineType, LinePoint } from '@flowgram.ai/free-layout-core';
3
3
  import * as _flowgram_ai_core from '@flowgram.ai/core';
4
4
  import { Layer, TransformData } from '@flowgram.ai/core';
5
5
  import { FlowRendererRegistry } from '@flowgram.ai/renderer';
@@ -125,30 +125,6 @@ interface ArrowRendererProps {
125
125
  */
126
126
  type ArrowRendererComponent = React.ComponentType<ArrowRendererProps>;
127
127
 
128
- /**
129
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
130
- * SPDX-License-Identifier: MIT
131
- */
132
-
133
- declare enum BezierControlType {
134
- RIGHT_TOP = 0,
135
- RIGHT_BOTTOM = 1,
136
- LEFT_TOP = 2,
137
- LEFT_BOTTOM = 3
138
- }
139
- /**
140
- * 获取贝塞尔曲线横向的控制节点
141
- * @param fromPos
142
- * @param toPos
143
- */
144
- declare function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[];
145
- /**
146
- * 获取贝塞尔曲线垂直方向的控制节点
147
- * @param fromPos 起始点
148
- * @param toPos 终点
149
- */
150
- declare function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[];
151
-
152
128
  /**
153
129
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
154
130
  * SPDX-License-Identifier: MIT
@@ -171,8 +147,8 @@ declare class WorkflowBezierLineContribution implements WorkflowLineRenderContri
171
147
  calcDistance(pos: IPoint): number;
172
148
  get bounds(): Rectangle;
173
149
  update(params: {
174
- fromPos: IPoint;
175
- toPos: IPoint;
150
+ fromPos: LinePoint;
151
+ toPos: LinePoint;
176
152
  }): void;
177
153
  private calcBezier;
178
154
  private getPath;
@@ -197,8 +173,8 @@ declare class WorkflowFoldLineContribution implements WorkflowLineRenderContribu
197
173
  calcDistance(pos: IPoint): number;
198
174
  get bounds(): Rectangle;
199
175
  update(params: {
200
- fromPos: IPoint;
201
- toPos: IPoint;
176
+ fromPos: LinePoint;
177
+ toPos: LinePoint;
202
178
  }): void;
203
179
  }
204
180
 
@@ -221,8 +197,8 @@ declare class WorkflowStraightLineContribution implements WorkflowLineRenderCont
221
197
  calcDistance(pos: IPoint): number;
222
198
  get bounds(): Rectangle;
223
199
  update(params: {
224
- fromPos: IPoint;
225
- toPos: IPoint;
200
+ fromPos: LinePoint;
201
+ toPos: LinePoint;
226
202
  }): void;
227
203
  }
228
204
 
@@ -253,31 +229,4 @@ declare class WorkflowArkLineContribution implements WorkflowLineRenderContribut
253
229
  private getArcPath;
254
230
  }
255
231
 
256
- /**
257
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
258
- * SPDX-License-Identifier: MIT
259
- */
260
-
261
- interface ManhattanData {
262
- points: IPoint[];
263
- path: string;
264
- bbox: Rectangle;
265
- }
266
- declare class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {
267
- static type: string;
268
- entity: WorkflowLineEntity;
269
- constructor(entity: WorkflowLineEntity);
270
- private data?;
271
- get path(): string;
272
- calcDistance(pos: IPoint): number;
273
- private getDistanceToLineSegment;
274
- get bounds(): Rectangle;
275
- update(params: {
276
- fromPos: IPoint;
277
- toPos: IPoint;
278
- }): void;
279
- private getManhattanPoints;
280
- private getPathFromPoints;
281
- }
282
-
283
- export { type ArcData, type ArrowRendererComponent, type ArrowRendererProps, BezierControlType, type BezierData, type FoldData, type FreeLinesPluginOptions, LINE_OFFSET, LINE_PADDING, type LineRenderProps, WorkflowLinesLayer as LinesLayer, type LinesLayerOptions, type ManhattanData, type StraightData, WorkflowArkLineContribution, WorkflowBezierLineContribution, WorkflowFoldLineContribution, WorkflowLinesLayer, WorkflowManhattanLineContribution, WorkflowPortRender, type WorkflowPortRenderProps, WorkflowStraightLineContribution, createFreeLinesPlugin, getBezierHorizontalControlPoints, getBezierVerticalControlPoints };
232
+ export { type ArcData, type ArrowRendererComponent, type ArrowRendererProps, type BezierData, type FoldData, type FreeLinesPluginOptions, LINE_OFFSET, LINE_PADDING, type LineRenderProps, WorkflowLinesLayer as LinesLayer, type LinesLayerOptions, type StraightData, WorkflowArkLineContribution, WorkflowBezierLineContribution, WorkflowFoldLineContribution, WorkflowLinesLayer, WorkflowPortRender, type WorkflowPortRenderProps, WorkflowStraightLineContribution, createFreeLinesPlugin };