refactor: adjust element type definition (#5865)

* refactor: remove Position and Points type

* refactor(elements): adjust elements type define
This commit is contained in:
Aaron 2024-06-14 09:19:43 +08:00 committed by GitHub
parent e91d473ebd
commit e0b4e44358
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 161 additions and 96 deletions

View File

@ -1,5 +1,5 @@
import { Path } from '@antv/g'; import { Path } from '@antv/g';
import type { IPointerEvent, Points } from '../types'; import type { IPointerEvent, Point } from '../types';
import { pointsToPath } from '../utils/path'; import { pointsToPath } from '../utils/path';
import type { BrushSelectOptions } from './brush-select'; import type { BrushSelectOptions } from './brush-select';
import { BrushSelect, getCursorPoint } from './brush-select'; import { BrushSelect, getCursorPoint } from './brush-select';
@ -21,7 +21,7 @@ export interface LassoSelectOptions extends BrushSelectOptions {}
* <en/> Select a group of elements with an irregular polygon. * <en/> Select a group of elements with an irregular polygon.
*/ */
export class LassoSelect extends BrushSelect { export class LassoSelect extends BrushSelect {
private points?: Points; private points?: Point[];
private pathShape?: Path; private pathShape?: Path;
/** /**

View File

@ -4,7 +4,7 @@ import type { BaseShapeStyleProps } from './shapes';
import { BaseShape } from './shapes'; import { BaseShape } from './shapes';
export abstract class BaseElement<T extends BaseShapeStyleProps> extends BaseShape<T> { export abstract class BaseElement<T extends BaseShapeStyleProps> extends BaseShape<T> {
public get parsedAttributes() { protected get parsedAttributes() {
return this.attributes as Required<T>; return this.attributes as Required<T>;
} }
@ -25,28 +25,4 @@ export abstract class BaseElement<T extends BaseShapeStyleProps> extends BaseSha
return animation; return animation;
} }
/**
* <zh/>
*
* <en/> Called after the element is created and the entrance animation is completed
* @override
*/
public onCreate() {}
/**
* <zh/>
*
* <en/> Called after the element is updated and the transition animation is completed
* @override
*/
public onUpdate() {}
/**
* <zh/> 退
*
* <en/> Called after the element completes the exit animation and is destroyed
* @override
*/
public onDestroy() {}
} }

View File

@ -3,10 +3,11 @@ import { isFunction } from '@antv/util';
import { COMBO_KEY } from '../../constants'; import { COMBO_KEY } from '../../constants';
import type { import type {
CollapsedMarkerStyleProps, CollapsedMarkerStyleProps,
Combo,
ID, ID,
NodeLikeData, NodeLikeData,
Padding, Padding,
Position, Point,
Prefix, Prefix,
STDSize, STDSize,
Size, Size,
@ -83,7 +84,10 @@ export interface BaseComboStyleProps
* *
* <en/> When customizing a combo, it is recommended to use this class as the base class. In this way, users only need to focus on the logic of drawing keyShape * <en/> When customizing a combo, it is recommended to use this class as the base class. In this way, users only need to focus on the logic of drawing keyShape
*/ */
export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStyleProps> extends BaseNode<S> { export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStyleProps>
extends BaseNode<S>
implements Combo
{
public type = 'combo'; public type = 'combo';
static defaultStyleProps: Partial<BaseComboStyleProps> = { static defaultStyleProps: Partial<BaseComboStyleProps> = {
@ -184,7 +188,7 @@ export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStylePr
return ancestors.length; return ancestors.length;
} }
public getComboPosition(attributes: Required<S>): Position { public getComboPosition(attributes: Required<S>): Point {
const { x = 0, y = 0, collapsed, context, childrenData = [] } = attributes; const { x = 0, y = 0, collapsed, context, childrenData = [] } = attributes;
if (childrenData.length === 0) return [+x, +y, 0]; if (childrenData.length === 0) return [+x, +y, 0];
@ -195,7 +199,7 @@ export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStylePr
if (descendants.length > 0) { if (descendants.length > 0) {
// combo 被收起,返回平均中心位置 / combo is collapsed, return the average center position // combo 被收起,返回平均中心位置 / combo is collapsed, return the average center position
const totalPosition = descendants.reduce((acc, datum) => add(acc, positionOf(datum)), [0, 0, 0] as Position); const totalPosition = descendants.reduce((acc, datum) => add(acc, positionOf(datum)), [0, 0, 0] as Point);
return divide(totalPosition, descendants.length); return divide(totalPosition, descendants.length);
} }
// empty combo // empty combo

View File

@ -4,6 +4,7 @@ import type { PathArray } from '@antv/util';
import { isFunction, pick } from '@antv/util'; import { isFunction, pick } from '@antv/util';
import type { import type {
BaseElementStyleProps, BaseElementStyleProps,
Edge,
EdgeArrowStyleProps, EdgeArrowStyleProps,
EdgeBadgeStyleProps, EdgeBadgeStyleProps,
EdgeKey, EdgeKey,
@ -170,7 +171,7 @@ type ParsedBaseEdgeStyleProps = Required<BaseEdgeStyleProps>;
* *
* <en/> Base class of the edge * <en/> Base class of the edge
*/ */
export abstract class BaseEdge extends BaseElement<BaseEdgeStyleProps> { export abstract class BaseEdge extends BaseElement<BaseEdgeStyleProps> implements Edge {
public type = 'edge'; public type = 'edge';
static defaultStyleProps: Partial<BaseEdgeStyleProps> = { static defaultStyleProps: Partial<BaseEdgeStyleProps> = {

View File

@ -5,6 +5,7 @@ import type { NodeData } from '../../spec';
import type { import type {
BaseElementStyleProps, BaseElementStyleProps,
ID, ID,
Node,
NodeBadgeStyleProps, NodeBadgeStyleProps,
NodeLabelStyleProps, NodeLabelStyleProps,
NodePortStyleProps, NodePortStyleProps,
@ -185,7 +186,10 @@ export interface BaseNodeStyleProps
* *
* <en/> Design document: https://www.yuque.com/antv/g6/gl1iof1xpzg6ed98 * <en/> Design document: https://www.yuque.com/antv/g6/gl1iof1xpzg6ed98
*/ */
export abstract class BaseNode<S extends BaseNodeStyleProps = BaseNodeStyleProps> extends BaseElement<S> { export abstract class BaseNode<S extends BaseNodeStyleProps = BaseNodeStyleProps>
extends BaseElement<S>
implements Node
{
public type = 'node'; public type = 'node';
static defaultStyleProps: Partial<BaseNodeStyleProps> = { static defaultStyleProps: Partial<BaseNodeStyleProps> = {

View File

@ -201,6 +201,8 @@ export type {
EdgeLabelStyleProps, EdgeLabelStyleProps,
Element, Element,
ElementDatum, ElementDatum,
ElementHooks,
ElementMethods,
ElementType, ElementType,
FitViewOptions, FitViewOptions,
IAnimateEvent, IAnimateEvent,

View File

@ -14,12 +14,11 @@ import type {
PartialEdgeData, PartialEdgeData,
PartialGraphData, PartialGraphData,
PartialNodeLikeData, PartialNodeLikeData,
Position, Point,
State, State,
} from '../types'; } from '../types';
import type { EdgeDirection } from '../types/edge'; import type { EdgeDirection } from '../types/edge';
import type { ElementType } from '../types/element'; import type { ElementType } from '../types/element';
import type { Point } from '../types/point';
import { cloneElementData, mergeElementsData } from '../utils/data'; import { cloneElementData, mergeElementsData } from '../utils/data';
import { arrayDiff } from '../utils/diff'; import { arrayDiff } from '../utils/diff';
import { toG6Data, toGraphlibData } from '../utils/graphlib'; import { toG6Data, toGraphlibData } from '../utils/graphlib';
@ -563,25 +562,25 @@ export class DataController {
model.mergeNodeData(id, value); model.mergeNodeData(id, value);
} }
public getElementPosition(id: ID): Position { public getElementPosition(id: ID): Point {
const datum = this.getElementDataById(id) as NodeLikeData; const datum = this.getElementDataById(id) as NodeLikeData;
return positionOf(datum); return positionOf(datum);
} }
public translateNodeBy(id: ID, offset: Position) { public translateNodeBy(id: ID, offset: Point) {
const curr = this.getElementPosition(id); const curr = this.getElementPosition(id);
const position = add(curr, [...offset, 0].slice(0, 3) as Point); const position = add(curr, [...offset, 0].slice(0, 3) as Point);
this.translateNodeTo(id, position); this.translateNodeTo(id, position);
} }
public translateNodeTo(id: ID, position: Position) { public translateNodeTo(id: ID, position: Point) {
const [x = 0, y = 0, z = 0] = position; const [x = 0, y = 0, z = 0] = position;
this.preventUpdateNodeLikeHierarchy(() => { this.preventUpdateNodeLikeHierarchy(() => {
this.updateNodeData([{ id, style: { x, y, z } }]); this.updateNodeData([{ id, style: { x, y, z } }]);
}); });
} }
public translateComboBy(id: ID, offset: Position) { public translateComboBy(id: ID, offset: Point) {
const [dx = 0, dy = 0, dz = 0] = offset; const [dx = 0, dy = 0, dz = 0] = offset;
if ([dx, dy, dz].some(isNaN) || [dx, dy, dz].every((o) => o === 0)) return; if ([dx, dy, dz].some(isNaN) || [dx, dy, dz].every((o) => o === 0)) return;
const combo = this.getComboData([id])[0]; const combo = this.getComboData([id])[0];
@ -608,7 +607,7 @@ export class DataController {
); );
} }
public translateComboTo(id: ID, position: Position) { public translateComboTo(id: ID, position: Point) {
if (position.some(isNaN)) return; if (position.some(isNaN)) return;
const [tx = 0, ty = 0, tz = 0] = position; const [tx = 0, ty = 0, tz = 0] = position;
const combo = this.getComboData([id])?.[0]; const combo = this.getComboData([id])?.[0];

View File

@ -389,7 +389,7 @@ export class ElementController {
{ {
after: () => { after: () => {
this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_CREATE, elementType, datum), context); this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_CREATE, elementType, datum), context);
element.onCreate(); element.onCreate?.();
}, },
}, },
); );
@ -457,7 +457,7 @@ export class ElementController {
if (stage === 'collapse') updateStyle(element, style); if (stage === 'collapse') updateStyle(element, style);
if (exactStage === 'hide') updateStyle(element, { visibility: getCachedStyle(element, 'visibility') }); if (exactStage === 'hide') updateStyle(element, { visibility: getCachedStyle(element, 'visibility') });
this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_UPDATE, elementType, datum), context); this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_UPDATE, elementType, datum), context);
element.onUpdate(); element.onUpdate?.();
}, },
}, },
); );
@ -496,7 +496,7 @@ export class ElementController {
after: () => { after: () => {
this.clearElement(id); this.clearElement(id);
element.destroy(); element.destroy();
element.onDestroy(); element.onDestroy?.();
this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_DESTROY, elementType, datum), context); this.emit(new ElementLifeCycleEvent(GraphEvent.AFTER_ELEMENT_DESTROY, elementType, datum), context);
}, },
}, },

View File

@ -36,7 +36,6 @@ import type {
PartialGraphData, PartialGraphData,
PartialNodeLikeData, PartialNodeLikeData,
Point, Point,
Position,
State, State,
Vector2, Vector2,
ViewportAnimationEffectTiming, ViewportAnimationEffectTiming,
@ -1184,7 +1183,7 @@ export class Graph extends EventEmitter {
* @param animation - <zh/> | <en/> whether to enable animation * @param animation - <zh/> | <en/> whether to enable animation
* @apiCategory element * @apiCategory element
*/ */
public async translateElementBy(id: ID, offset: Position, animation?: boolean): Promise<void>; public async translateElementBy(id: ID, offset: Point, animation?: boolean): Promise<void>;
/** /**
* <zh/> * <zh/>
* *
@ -1193,15 +1192,15 @@ export class Graph extends EventEmitter {
* @param animation - <zh/> | <en/> whether to enable animation * @param animation - <zh/> | <en/> whether to enable animation
* @apiCategory element * @apiCategory element
*/ */
public async translateElementBy(offsets: Record<ID, Position>, animation?: boolean): Promise<void>; public async translateElementBy(offsets: Record<ID, Point>, animation?: boolean): Promise<void>;
public async translateElementBy( public async translateElementBy(
args1: ID | Record<ID, Position>, args1: ID | Record<ID, Point>,
args2?: Position | boolean, args2?: Point | boolean,
args3: boolean = true, args3: boolean = true,
): Promise<void> { ): Promise<void> {
const [config, animation] = isObject(args1) const [config, animation] = isObject(args1)
? [args1, (args2 as boolean) ?? true] ? [args1, (args2 as boolean) ?? true]
: [{ [args1 as ID]: args2 as Position }, args3]; : [{ [args1 as ID]: args2 as Point }, args3];
Object.entries(config).forEach(([id, offset]) => this.context.model.translateNodeBy(id, offset)); Object.entries(config).forEach(([id, offset]) => this.context.model.translateNodeBy(id, offset));
await this.context.element!.draw({ animation })?.finished; await this.context.element!.draw({ animation })?.finished;
@ -1216,7 +1215,7 @@ export class Graph extends EventEmitter {
* @param animation - <zh/> | <en/> whether to enable animation * @param animation - <zh/> | <en/> whether to enable animation
* @apiCategory element * @apiCategory element
*/ */
public async translateElementTo(id: ID, position: Position, animation?: boolean): Promise<void>; public async translateElementTo(id: ID, position: Point, animation?: boolean): Promise<void>;
/** /**
* <zh/> * <zh/>
* *
@ -1225,15 +1224,15 @@ export class Graph extends EventEmitter {
* @param animation - <zh/> | <en/> whether to enable animation * @param animation - <zh/> | <en/> whether to enable animation
* @apiCategory element * @apiCategory element
*/ */
public async translateElementTo(positions: Record<ID, Position>, animation?: boolean): Promise<void>; public async translateElementTo(positions: Record<ID, Point>, animation?: boolean): Promise<void>;
public async translateElementTo( public async translateElementTo(
args1: ID | Record<ID, Position>, args1: ID | Record<ID, Point>,
args2?: boolean | Position, args2?: boolean | Point,
args3: boolean = true, args3: boolean = true,
): Promise<void> { ): Promise<void> {
const [config, animation] = isObject(args1) const [config, animation] = isObject(args1)
? [args1, (args2 as boolean) ?? true] ? [args1, (args2 as boolean) ?? true]
: [{ [args1 as ID]: args2 as Position }, args3]; : [{ [args1 as ID]: args2 as Point }, args3];
Object.entries(config).forEach(([id, position]) => this.context.model.translateNodeTo(id, position)); Object.entries(config).forEach(([id, position]) => this.context.model.translateNodeTo(id, position));
await this.context.element!.draw({ animation })?.finished; await this.context.element!.draw({ animation })?.finished;
@ -1247,7 +1246,7 @@ export class Graph extends EventEmitter {
* @returns <zh/> | <en/> element position * @returns <zh/> | <en/> element position
* @apiCategory element * @apiCategory element
*/ */
public getElementPosition(id: ID): Position { public getElementPosition(id: ID): Point {
return this.context.model.getElementPosition(id); return this.context.model.getElementPosition(id);
} }

View File

@ -1,25 +1,120 @@
import type { BaseStyleProps } from '@antv/g'; import type { BaseStyleProps, DisplayObject } from '@antv/g';
import type { BaseCombo } from '../elements/combos';
import type { BaseEdge } from '../elements/edges';
import type { BaseNode } from '../elements/nodes';
import type { RuntimeContext } from '../runtime/types'; import type { RuntimeContext } from '../runtime/types';
import type { ComboOptions, EdgeOptions, NodeOptions } from '../spec'; import type { ComboOptions, EdgeOptions, NodeOptions } from '../spec';
import type { Point, Port } from '../types';
/**
* <zh/>
*
* <en/> Node type
*/
export interface Node extends DisplayObject, ElementHooks, ElementMethods {
/**
* <zh/>
*
* <en/> Get the ports
*/
getPorts(): Record<string, Port>;
/**
* <zh/>
*
* <en/> Get the center position of the node
*/
getCenter(): Point;
/**
* <zh/>
*
* <en/> Get the intersection point
* @param point - <zh/> | <en/> external position
* @returns <zh/> | <en/> intersection point
* @description
* <zh/>
*
* <en/> Given an external position, return the intersection point of the edge between the current node and the position and the node
*/
getIntersectPoint(point: Point): Point;
}
/**
* <zh/>
*
* <en/> Edge type
*/
export interface Edge extends DisplayObject, ElementHooks, ElementMethods {}
/**
* <zh/>
*
* <en/> Combo type
*/
export interface Combo extends Node {
/**
* <zh/>
*
* <en/> Get the position of the combo
* @param attributes - <zh/> | <en/> combo attributes
*/
getComboPosition(attributes: Record<string, unknown>): Point;
}
export type Element = Node | Edge | Combo;
export type ElementType = 'node' | 'edge' | 'combo'; export type ElementType = 'node' | 'edge' | 'combo';
export type ElementOptions = NodeOptions | EdgeOptions | ComboOptions; export type ElementOptions = NodeOptions | EdgeOptions | ComboOptions;
export type Node = BaseNode<any>;
export type Edge = BaseEdge;
export type Combo = BaseCombo<any>;
export type Element = Node | Edge | Combo;
export interface BaseElementStyleProps extends BaseStyleProps { export interface BaseElementStyleProps extends BaseStyleProps {
/** /**
* @internal * @internal
*/ */
context?: RuntimeContext; context?: RuntimeContext;
} }
/**
* <zh/>
*
* <en/> Element methods
*/
export interface ElementMethods {
/**
* <zh/>
*
* <en/> Get the subgraph in the current element
* @param shapeID - <zh/> ID | <en/> Subgraph ID
* @returns <zh/> | <en/> Subgraph
*/
getShape<T extends DisplayObject = DisplayObject>(shapeID: string): T;
}
/**
* <zh/>
*
* <en/> Element hooks
*/
export interface ElementHooks {
/**
* <zh/>
*
* <en/> Called after the element is created and the entrance animation is completed
* @override
*/
onCreate?: () => void;
/**
* <zh/>
*
* <en/> Called after the element is updated and the transition animation is completed
* @override
*/
onUpdate?: () => void;
/**
* <zh/> 退
*
* <en/> Called after the element completes the exit animation and is destroyed
* @override
*/
onDestroy?: () => void;
}

View File

@ -16,7 +16,6 @@ export type * from './node';
export type * from './padding'; export type * from './padding';
export type * from './placement'; export type * from './placement';
export type * from './point'; export type * from './point';
export type * from './position';
export type * from './prefix'; export type * from './prefix';
export type * from './size'; export type * from './size';
export type * from './state'; export type * from './state';

View File

@ -1,2 +1 @@
export type Point = [number, number] | [number, number, number] | Float32Array; export type Point = [number, number] | [number, number, number] | Float32Array;
export type Points = Point[];

View File

@ -1,3 +0,0 @@
import type { Point } from './point';
export type Position = Point;

View File

@ -1,17 +1,7 @@
import type { AABB, DisplayObject, TextStyleProps } from '@antv/g'; import type { AABB, DisplayObject, TextStyleProps } from '@antv/g';
import { get, isString, set } from '@antv/util'; import { get, isString, set } from '@antv/util';
import { BaseCombo, BaseEdge, BaseNode } from '../elements'; import { BaseCombo, BaseEdge, BaseNode } from '../elements';
import type { import type { Combo, Edge, Element, Node, NodePortStyleProps, Placement, Point, TriangleDirection } from '../types';
Combo,
Edge,
Element,
Node,
NodePortStyleProps,
Placement,
Point,
Position,
TriangleDirection,
} from '../types';
import type { NodeLabelStyleProps, Port } from '../types/node'; import type { NodeLabelStyleProps, Port } from '../types/node';
import { getBBoxHeight, getBBoxWidth } from './bbox'; import { getBBoxHeight, getBBoxWidth } from './bbox';
import { isPoint } from './is'; import { isPoint } from './is';
@ -148,7 +138,7 @@ export function isSimplePort(portStyle: NodePortStyleProps): boolean {
* @param port - <zh/> | <en/> Port * @param port - <zh/> | <en/> Port
* @returns <zh/> | <en/> Port Position * @returns <zh/> | <en/> Port Position
*/ */
export function getPortPosition(port: Port): Position { export function getPortPosition(port: Port): Point {
return isPoint(port) ? port : port.getPosition(); return isPoint(port) ? port : port.getPosition();
} }
@ -212,7 +202,7 @@ export function findPort(node: Node, oppositeNode: Node, portKey?: string, oppos
* @param portKey * @param portKey
* @returns <zh/> | <en/> Connection Point * @returns <zh/> | <en/> Connection Point
*/ */
function findConnectionPoints(node: Node, portKey?: string): Position[] { function findConnectionPoints(node: Node, portKey?: string): Point[] {
const allPortsMap = getAllPorts(node); const allPortsMap = getAllPorts(node);
if (portKey) return [getPortPosition(allPortsMap[portKey])]; if (portKey) return [getPortPosition(allPortsMap[portKey])];
const oppositePorts = Object.values(allPortsMap); const oppositePorts = Object.values(allPortsMap);

View File

@ -1,15 +1,15 @@
import type { PathArray, PathCommand } from '@antv/util'; import type { PathArray, PathCommand } from '@antv/util';
import type { Point, Points } from '../types'; import type { Point } from '../types';
/** /**
* <zh/> points path * <zh/> points path
* *
* <en/> points transfrom path. * <en/> points transform path.
* @param points Point[] * @param points Point[]
* @param isClose boolean * @param isClose boolean
* @returns path string[][] * @returns path string[][]
*/ */
export function pointsToPath(points: Points, isClose = true): PathArray { export function pointsToPath(points: Point[], isClose = true): PathArray {
const path = []; const path = [];
points.forEach((point, index) => { points.forEach((point, index) => {

View File

@ -1,5 +1,5 @@
import type { AABB } from '@antv/g'; import type { AABB } from '@antv/g';
import type { Anchor, NodeLikeData, Placement, Points, Position, RelativePlacement } from '../types'; import type { Anchor, NodeLikeData, Placement, Point, RelativePlacement } from '../types';
import { parseAnchor } from './anchor'; import { parseAnchor } from './anchor';
import { parsePlacement } from './placement'; import { parsePlacement } from './placement';
@ -10,7 +10,7 @@ import { parsePlacement } from './placement';
* @param datum - <zh/> / combo | <en/> data of node/combo * @param datum - <zh/> / combo | <en/> data of node/combo
* @returns - <zh/> | <en/> position * @returns - <zh/> | <en/> position
*/ */
export function positionOf(datum: NodeLikeData): Position { export function positionOf(datum: NodeLikeData): Point {
const { x = 0, y = 0, z = 0 } = datum.style || {}; const { x = 0, y = 0, z = 0 } = datum.style || {};
return [+x, +y, +z]; return [+x, +y, +z];
} }
@ -20,10 +20,10 @@ export function positionOf(datum: NodeLikeData): Position {
* *
* <en/> Get position by relative placement * <en/> Get position by relative placement
* @param bbox - <zh/> | <en/> element bounding box * @param bbox - <zh/> | <en/> element bounding box
* @param placement - <zh/> | <en/> Position relative to element * @param placement - <zh/> | <en/> Point relative to element
* @returns - <zh/> | <en/> position * @returns - <zh/> | <en/> position
*/ */
export function getXYByRelativePlacement(bbox: AABB, placement: RelativePlacement): Position { export function getXYByRelativePlacement(bbox: AABB, placement: RelativePlacement): Point {
const [x, y] = placement; const [x, y] = placement;
const { min, max } = bbox; const { min, max } = bbox;
return [min[0] + x * (max[0] - min[0]), min[1] + y * (max[1] - min[1])]; return [min[0] + x * (max[0] - min[0]), min[1] + y * (max[1] - min[1])];
@ -34,10 +34,10 @@ export function getXYByRelativePlacement(bbox: AABB, placement: RelativePlacemen
* *
* <en/> Get position by placement * <en/> Get position by placement
* @param bbox - <zh/> | <en/> element bounding box * @param bbox - <zh/> | <en/> element bounding box
* @param placement - <zh/> | <en/> Position relative to element * @param placement - <zh/> | <en/> Point relative to element
* @returns - <zh/> | <en/> position * @returns - <zh/> | <en/> position
*/ */
export function getXYByPlacement(bbox: AABB, placement: Placement = 'center'): Position { export function getXYByPlacement(bbox: AABB, placement: Placement = 'center'): Point {
const relativePlacement = parsePlacement(placement); const relativePlacement = parsePlacement(placement);
return getXYByRelativePlacement(bbox, relativePlacement); return getXYByRelativePlacement(bbox, relativePlacement);
} }
@ -50,7 +50,7 @@ export function getXYByPlacement(bbox: AABB, placement: Placement = 'center'): P
* @param anchor - <zh/> | <en/> Anchor * @param anchor - <zh/> | <en/> Anchor
* @returns - <zh/> | <en/> position * @returns - <zh/> | <en/> position
*/ */
export function getXYByAnchor(bbox: AABB, anchor: Anchor): Position { export function getXYByAnchor(bbox: AABB, anchor: Anchor): Point {
const parsedAnchor = parseAnchor(anchor); const parsedAnchor = parseAnchor(anchor);
return getXYByRelativePlacement(bbox, parsedAnchor as RelativePlacement); return getXYByRelativePlacement(bbox, parsedAnchor as RelativePlacement);
} }
@ -62,7 +62,7 @@ export function getXYByAnchor(bbox: AABB, anchor: Anchor): Position {
* @param points Points * @param points Points
* @returns `{ left: number; right: number; top: number; bottom: number }` * @returns `{ left: number; right: number; top: number; bottom: number }`
*/ */
export const getPositionByRectPoints = (points: Points) => { export const getPositionByRectPoints = (points: Point[]) => {
const [p1, p2] = points; const [p1, p2] = points;
return { return {
left: Math.min(p1[0], p2[0]), left: Math.min(p1[0], p2[0]),