diff --git a/src/utils/follow.ts b/src/utils/follow.ts new file mode 100644 index 00000000..0d93a9b2 --- /dev/null +++ b/src/utils/follow.ts @@ -0,0 +1,40 @@ +import {Node} from 'konva/lib/Node'; +import {Center, flipOrigin, Origin} from '../types'; +import {getOriginDelta, isLayoutNode} from '../components/ILayoutNode'; + +export interface FollowSubscription { + dispose(): void; + target(newTarget: Node): void; +} + +export function follow( + source: Node, + target: Node, + direction?: Origin, +): FollowSubscription { + direction ??= isLayoutNode(source) + ? flipOrigin(source.getOrigin(), Center.Vertical) + : Origin.TopLeft; + + const update = () => { + const rect = target.getClientRect({relativeTo: target.getLayer()}); + const offset = getOriginDelta(rect, Origin.TopLeft, direction); + source.position({ + x: rect.x + offset.x, + y: rect.y + offset.y, + }); + }; + + target.on('absoluteTransformChange', update); + update(); + + return { + dispose: () => target.off('absoluteTransformChange', update), + target: (newTarget: Node) => { + target.off('absoluteTransformChange', update); + target = newTarget; + target.on('absoluteTransformChange', update); + update(); + }, + }; +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 2d090d0c..2cdf10d3 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ -export * from './pop'; \ No newline at end of file +export * from './pop'; +export * from './follow'; \ No newline at end of file