UNPKG

@antv/g6

Version:

A Graph Visualization Framework in JavaScript

96 lines (77 loc) 3.38 kB
import type { DisplayObject, IAnimation } from '@antv/g'; import { upperFirst } from '@antv/util'; import { createAnimationsProxy, inferDefaultValue, preprocessKeyframes } from '../utils/animation'; import { replaceTranslateInTransform } from '../utils/transform'; import type { AnimationExecutor } from './types'; /** * <zh/> 动画语法执行器 * * <en/> Animation syntax executor * @param element - <zh/> 要执行动画的图形 | <en/> shape to execute animation * @param keyframes - <zh/> 动画关键帧 | <en/> animation keyframes * @param options - <zh/> 动画语法 | <en/> animation syntax * @returns <zh/> 动画实例 | <en/> animation instance */ export const executor: AnimationExecutor = (element, keyframes, options) => { if (!options.length) return null; const [originalStyle, modifiedStyle] = keyframes; /** * <zh/> 获取图形关键帧样式 * * <en/> Get the keyframe style of the shape * @param shapeID - <zh/> 图形 ID | <en/> shape ID * @returns <zh/> 图形关键帧样式 | <en/> keyframe style of the shape */ const getKeyframeStyle = ( shapeID?: string, ): { shape: DisplayObject; fromStyle: Record<string, any>; toStyle: Record<string, any> } | null => { if (shapeID) { const shape = element.getShape(shapeID); if (!shape) return null; const name = `get${upperFirst(shapeID)}Style` as keyof typeof element; const styler: (attrs?: Record<string, unknown>) => Record<string, unknown> = element?.[name]?.bind(element) || ((attrs) => attrs); const fromStyle = styler?.(originalStyle) || {}; const toStyle = styler?.(modifiedStyle) || {}; return { shape, fromStyle, toStyle }; } else { const shape = element; return { shape, fromStyle: originalStyle, toStyle: modifiedStyle }; } }; let mainResult: IAnimation; const subResults = options .map(({ fields, shape: shapeID, states: enabledStates, ...effectTiming }) => { const keyframeStyle = getKeyframeStyle(shapeID); if (!keyframeStyle) return null; const { shape, fromStyle, toStyle } = keyframeStyle; const keyframes: Keyframe[] = [{}, {}]; fields.forEach((attr) => { Object.assign(keyframes[0], { [attr]: fromStyle[attr] ?? inferDefaultValue(attr) }); Object.assign(keyframes[1], { [attr]: toStyle[attr] ?? inferDefaultValue(attr) }); }); // x/y -> translate if (keyframes.some((keyframe) => Object.keys(keyframe).some((attr) => ['x', 'y', 'z'].includes(attr)))) { const { x = 0, y = 0, z, transform = '' } = shape.attributes || {}; keyframes.forEach((keyframe) => { // @ts-expect-error ignore type error keyframe.transform = replaceTranslateInTransform( (keyframe.x as number) ?? (x as number), (keyframe.y as number) ?? (y as number), (keyframe.z as number) ?? (z as number), transform, ); }); } const result = shape.animate(preprocessKeyframes(keyframes), effectTiming); if (shapeID === undefined) mainResult = result!; return result; }) .filter(Boolean) as IAnimation[]; const result = mainResult! || subResults?.[0]; if (!result) return null; return createAnimationsProxy( result, subResults.filter((result) => result !== result), ); };