diff --git a/packages/f2/src/canvas/animation/animator.ts b/packages/f2/src/canvas/animation/animator.ts index dbd93d6eb..5516d71c2 100644 --- a/packages/f2/src/canvas/animation/animator.ts +++ b/packages/f2/src/canvas/animation/animator.ts @@ -11,8 +11,8 @@ class Animator { // 动画定义 animation: Animation; - // 裁剪区动画的shape - clip: any; + // 是否是裁剪动画 + isClip: boolean = false; // 缓动函数 easing: EasingFunction; @@ -33,7 +33,7 @@ class Animator { this.element = element; this.animation = animation; - const { property = [], easing, duration, delay = 0, start, end, onFrame } = animation; + const { property = [], easing, duration, delay = 0, start, end, onFrame, isClip } = animation; const interpolates = property.map((name) => { if (isString(name)) { return interpolate(start[name], end[name]); @@ -53,6 +53,7 @@ class Animator { this.onFrame = onFrame; this.totalDuration = duration + delay; + this.isClip = isClip; // 更新到初始状态 this.update(0, 0); @@ -80,7 +81,7 @@ class Animator { } update(t: number, time) { - const { element, clip, interpolates, property, onFrame } = this; + const { element, interpolates, property, onFrame } = this; let attrs = {}; for (let i = property.length - 1; i >= 0; i--) { const name = property[i]; @@ -97,23 +98,18 @@ class Animator { ...this.onFrame(t, time), }; } - if (clip) { - clip.attr(attrs); - } else { - element.attr(attrs); - } + element.attr(attrs); } onEnd() { - const { animation, clip, element } = this; + const { animation, isClip, element } = this; const { onEnd } = animation; onEnd && onEnd.call(this); - if (clip) { + if (isClip) { // 如果是裁剪区动画,要移除裁剪区 - clip.remove(true); - element.attr('clip', null); + element.remove(true); } // 如果当前元素状态被标记为删除,等动画结束后直接删除 diff --git a/packages/f2/src/canvas/animation/index.ts b/packages/f2/src/canvas/animation/index.ts index 43bf5a2b2..c13b301a3 100644 --- a/packages/f2/src/canvas/animation/index.ts +++ b/packages/f2/src/canvas/animation/index.ts @@ -25,9 +25,9 @@ class Animation { } createAnimator(element, animation) { - const { duration } = animation; + const { duration, property, onFrame } = animation; // 校验关键参数 - if (!duration) { + if (!duration || ((!property || !property.length) && !onFrame)) { return; } return new Animator(element, animation); @@ -59,11 +59,12 @@ class Animation { const { clip } = animation; // 如果有裁剪区动画,处理裁剪区动画 if (clip) { - const animator = this.createAnimator(element, clip); + clip.isClip = true; + const { element: clipElement } = clip; + const animator = this.createAnimator(clipElement, clip); if (animator) { - animator.clip = clip.element; maxDuration = Math.max(maxDuration, animator.totalDuration); - element.attr('clip', clip.element); + element.attr('clip', clipElement); animators.push(animator); } } diff --git a/packages/f2/src/canvas/animation/interface.ts b/packages/f2/src/canvas/animation/interface.ts index 8f5d8d8e5..effa7ba94 100644 --- a/packages/f2/src/canvas/animation/interface.ts +++ b/packages/f2/src/canvas/animation/interface.ts @@ -8,7 +8,7 @@ export interface Animation { delay?: number; property?: string[]; // 裁剪区动画 - clip?: any; + isClip?: boolean; // start 的 attrs start?: any; // end 的 attrs diff --git a/packages/f2/src/components/interval/view/polar.tsx b/packages/f2/src/components/interval/view/polar.tsx index ad504549f..a508b3411 100644 --- a/packages/f2/src/components/interval/view/polar.tsx +++ b/packages/f2/src/components/interval/view/polar.tsx @@ -3,9 +3,34 @@ import { deepMix } from '@antv/util'; export default (props) => { const { coord, records, animation } = props; - const { center } = coord; + const { center, startAngle, endAngle, radius } = coord; return ( - + {records.map((record) => { const { key, children } = record; return ( diff --git a/packages/f2/src/coord/polar.ts b/packages/f2/src/coord/polar.ts index 2f834a787..7c7e30d75 100644 --- a/packages/f2/src/coord/polar.ts +++ b/packages/f2/src/coord/polar.ts @@ -35,6 +35,8 @@ class Polar extends Base { this.x = x; this.y = y; + this.startAngle = startAngle; + this.endAngle = endAngle; this.radius = radius; this.innnerRadius = innerRadiusRatio * radius; return this; diff --git a/packages/f2/src/jsx/animation/index.ts b/packages/f2/src/jsx/animation/index.ts index 451ed36d1..9291202d2 100644 --- a/packages/f2/src/jsx/animation/index.ts +++ b/packages/f2/src/jsx/animation/index.ts @@ -1,23 +1,17 @@ import { ELEMENT_DELETE } from '../elementStatus'; -import { Shape } from '@antv/f2-graphic'; - -function createClipElement(type: string, config) { - return new Shape[type](config); -} +import createClipElement from '../createClipElement'; export default (element, animation, nextAttrs, lastAttrs) => { if (!animation) return null; // 获取shape的默认属性 const status = element.get('status'); - // const { appear, update, leave } = animationCfg; - // const animation = status === ELEMENT_DELETE ? leave : ( lastAttrs ? update : appear ); - // if (!animation) return; const { clip, start, end, easing, delay, duration } = animation; + // 裁剪动画 if (clip) { - const { type, start } = clip; + const { type, attrs } = clip; const clipElement = createClipElement(type, { - attrs: start, + attrs, }); // 默认用 animation 配置里的 easing 和 duration clip.easing = clip.easing || easing; diff --git a/packages/f2/src/jsx/createClipElement.ts b/packages/f2/src/jsx/createClipElement.ts new file mode 100644 index 000000000..3684dd77f --- /dev/null +++ b/packages/f2/src/jsx/createClipElement.ts @@ -0,0 +1,8 @@ +import { upperFirst } from '@antv/util'; +import { Shape } from '@antv/f2-graphic'; + +function createClipElement(type: string, config) { + return new Shape[upperFirst(type)](config); +} + +export default createClipElement; diff --git a/packages/f2/src/jsx/render.ts b/packages/f2/src/jsx/render.ts index 4ca5858d8..c59a9f490 100644 --- a/packages/f2/src/jsx/render.ts +++ b/packages/f2/src/jsx/render.ts @@ -1,15 +1,11 @@ import JSX from './interface'; import { extendMap, px2hd } from '../util'; -import { omit, upperFirst } from '@antv/util'; +import { omit } from '@antv/util'; import computeLayout from './css-layout'; import getShapeAttrs from './shape'; import getAnimation from './animation'; import { ELEMENT_DELETE } from './elementStatus'; -import { Shape } from '@antv/f2-graphic'; - -function createClipElement(type: string, config) { - return new Shape[upperFirst(type)](config); -} +import createClipElement from './createClipElement'; // 转换成布局所需要的布局树 function createNodeTree(element, container) { diff --git a/packages/graphic/src/engine/element.ts b/packages/graphic/src/engine/element.ts index 5372f25d0..7672e1d38 100644 --- a/packages/graphic/src/engine/element.ts +++ b/packages/graphic/src/engine/element.ts @@ -190,7 +190,7 @@ class Element { setContext(context) { const clip = this._attrs.attrs.clip; context.save(); - if (clip) { + if (clip && !clip._attrs.destroyed) { clip.resetTransform(context); clip.createPath(context); context.clip();