UNPKG

@antv/g6

Version:

A Graph Visualization Framework in JavaScript

113 lines (100 loc) 3.63 kB
import type { DisplayObjectConfig, RectStyleProps as GRectStyleProps, Group } from '@antv/g'; import { ImageStyleProps as GImageStyleProps, Rect as GRect } from '@antv/g'; import { ICON_SIZE_RATIO } from '../../constants/element'; import { subStyleProps } from '../../utils/prefix'; import { mergeOptions } from '../../utils/style'; import { add } from '../../utils/vector'; import type { IconStyleProps } from '../shapes'; import { Image as ImageShape } from '../shapes'; import { connectImage, dispatchPositionChange } from '../shapes/image'; import type { BaseNodeStyleProps } from './base-node'; import { BaseNode } from './base-node'; /** * <zh/> 图片节点样式配置项 * * <en/> Image node style props */ export interface ImageStyleProps extends BaseNodeStyleProps { /** * <zh/> 图片来源,即图片地址字符串 * * <en/> Image source, i.e. image address string */ img?: string | HTMLImageElement; /** * <zh/> 该属性为 img 的别名 * * <en/> This property is an alias for img */ src?: string | HTMLImageElement; } /** * <zh/> 图片节点 * * <en/> Image node */ export class Image extends BaseNode<ImageStyleProps> { static defaultStyleProps: Partial<ImageStyleProps> = { size: 32, }; constructor(options: DisplayObjectConfig<ImageStyleProps>) { super(mergeOptions({ style: Image.defaultStyleProps }, options)); } protected getKeyStyle(attributes: Required<ImageStyleProps>): GImageStyleProps { const [width, height] = this.getSize(attributes); const { fillOpacity, opacity = fillOpacity, ...keyStyle } = super.getKeyStyle(attributes); return { opacity, ...keyStyle, width, height, x: -width / 2, y: -height / 2, }; } public getBounds() { return this.getShape('key').getBounds(); } protected getHaloStyle(attributes: Required<ImageStyleProps>): false | GRectStyleProps { if (attributes.halo === false) return false; const { fill: keyStyleFill, stroke: keyStyleStroke, ...keyStyle } = this.getShape<GRect>('key').attributes; const haloStyle = subStyleProps(this.getGraphicStyle(attributes), 'halo'); const haloLineWidth = Number(haloStyle.lineWidth); const [width, height] = add(this.getSize(attributes), [haloLineWidth, haloLineWidth]); const { lineWidth } = haloStyle; const recalculate = { fill: 'transparent', lineWidth: lineWidth / 2, width: width - lineWidth / 2, height: height - lineWidth / 2, x: -(width - lineWidth / 2) / 2, y: -(height - lineWidth / 2) / 2, }; return { ...haloStyle, ...recalculate }; } protected getIconStyle(attributes: Required<ImageStyleProps>): false | IconStyleProps { const style = super.getIconStyle(attributes); const [width, height] = this.getSize(attributes); return style ? ({ width: width * ICON_SIZE_RATIO, height: height * ICON_SIZE_RATIO, ...style, } as IconStyleProps) : false; } protected drawKeyShape(attributes: Required<ImageStyleProps>, container: Group): ImageShape | undefined { const image = this.upsert('key', ImageShape, this.getKeyStyle(attributes), container); connectImage(this); return image; } protected drawHaloShape(attributes: Required<ImageStyleProps>, container: Group): void { this.upsert('halo', GRect, this.getHaloStyle(attributes), container); } public update(attr?: Partial<ImageStyleProps>): void { super.update(attr); if (attr && ('x' in attr || 'y' in attr || 'z' in attr)) { dispatchPositionChange(this); } } }