UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

93 lines (83 loc) 2.11 kB
import type { Point } from '../../geometry' import type { NodeAnchorDefinition, NodeAnchorResolvedDefinition, } from './index' import { type ResolveOptions, resolve } from './util' export interface MiddleSideEndpointOptions extends ResolveOptions { rotate?: boolean padding?: number direction?: 'H' | 'V' } const middleSide: NodeAnchorResolvedDefinition<MiddleSideEndpointOptions> = ( view, magnet, refPoint, options, ) => { let bbox let angle = 0 let center const node = view.cell if (options.rotate) { bbox = view.getUnrotatedBBoxOfElement(magnet) center = node.getBBox().getCenter() angle = node.getAngle() } else { if (node.visible) { bbox = view.getBBoxOfElement(magnet) } else { bbox = view.cell.getBBox() } } const padding = options.padding if (padding != null && Number.isFinite(padding)) { bbox.inflate(padding) } if (options.rotate) { refPoint.rotate(angle, center) } const side = bbox.getNearestSideToPoint(refPoint) let result: Point switch (side) { case 'left': result = bbox.getLeftMiddle() break case 'right': result = bbox.getRightMiddle() break case 'top': result = bbox.getTopCenter() break case 'bottom': result = bbox.getBottomCenter() break default: break } const direction = options.direction if (direction === 'H') { if (side === 'top' || side === 'bottom') { if (refPoint.x <= bbox.x + bbox.width) { result = bbox.getLeftMiddle() } else { result = bbox.getRightMiddle() } } } else if (direction === 'V') { if (refPoint.y <= bbox.y + bbox.height) { result = bbox.getTopCenter() } else { result = bbox.getBottomCenter() } } return options.rotate ? result!.rotate(-angle, center) : result! } /** * Places the anchor of the edge in the middle of the side of view bbox * closest to the other endpoint. */ export const midSide = resolve< NodeAnchorResolvedDefinition<ResolveOptions>, NodeAnchorDefinition<ResolveOptions> >(middleSide)