diff --git a/src/animate/index.ts b/src/animate/index.ts index e4bc030e9d..bc079de99a 100644 --- a/src/animate/index.ts +++ b/src/animate/index.ts @@ -181,6 +181,7 @@ function parseAnimateConfig(animateCfg: AnimateCfg, data: Data | Datum): GAnimat easing: isFunction(animateCfg.easing) ? animateCfg.easing(data) : animateCfg.easing, duration: isFunction(animateCfg.duration) ? animateCfg.duration(data) : animateCfg.duration, callback: animateCfg.callback, + repeat: animateCfg.repeat, }; } diff --git a/src/interface.ts b/src/interface.ts index ffd65bd9b9..761a440177 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -142,6 +142,8 @@ export interface AnimateCfg { readonly delay?: number | AnimateDelayCallback; /** 动画执行结束后的回调函数 */ readonly callback?: () => any; + /** 动画是否重复 */ + readonly repeat?: boolean; } /** 传递给 G 的动画配置,duration 必须提供 */ @@ -156,6 +158,8 @@ export interface GAnimateCfg { readonly delay?: number; /** 动画执行结束后的回调函数 */ readonly callback?: () => any; + /** 动画是否重复 */ + readonly repeat?: boolean; } // ============================ Geometry 接口相关的类型定义 ============================ diff --git a/tests/unit/animate/index-spec.ts b/tests/unit/animate/index-spec.ts index 97ec72d110..a22fcea3dd 100644 --- a/tests/unit/animate/index-spec.ts +++ b/tests/unit/animate/index-spec.ts @@ -1,5 +1,5 @@ import { getCoordinate } from '@antv/coord'; -import { isNumberEqual } from '@antv/util'; +import { every, isNumberEqual, some } from '@antv/util'; import { doAnimate, doGroupAppearAnimate, getDefaultAnimateCfg } from '../../../src/animate/index'; import { delay } from '../../util/delay'; import { createCanvas, createDiv, removeDom } from '../../util/dom'; @@ -180,10 +180,58 @@ describe('Animate', () => { { x: 0, y: 400 } ); - setTimeout(() => { - expect(group.attr('matrix')).toEqual([1, 0, 0, 0, 1, 0, 0, 0, 1]); - done(); + /** 不重复执行动画,每一次都等 */ + const matries = []; + const interval = setInterval(() => { + if (matries.length < 5) { + matries.push(group.attr('matrix')); + } else { + clearInterval(interval); + done(); + } }, 550); + every(matries, (m) => expect(m.toEqual([1, 0, 0, 0, 1, 0, 0, 0, 1]))); + + group.destroy(); + }); + + it('doGroupAppearAnimate: repeat', async (done) => { + const group = canvas.addGroup(); + group.addShape({ + type: 'circle', + attrs: { + x: 150, + y: 150, + r: 50, + fill: 'red', + }, + }); + + doGroupAppearAnimate( + group, + { + duration: 500, + easing: 'easeQuadOut', + repeat: true, + }, + 'interval', + polarCoord, + { x: 0, y: 400 } + ); + + /** 重复执行动画,必有一次不等 */ + const matries = []; + const interval = setInterval(() => { + if (matries.length < 5) { + matries.push(group.attr('matrix')); + } else { + clearInterval(interval); + done(); + } + }, 550); + some(matries, (m) => expect(m.not.toEqual([1, 0, 0, 0, 1, 0, 0, 0, 1]))); + + group.destroy(); }); afterEach(() => {