Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions packages/vchart/src/animation/callback-disappear.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { AStageAnimate } from '@visactor/vrender-animate';
import { EasingType } from '@visactor/vrender-core';

/**
* 特效动画基类,提取公共的WebGL和Canvas 2D操作
*/
export class CallbackDisappearAnimate extends AStageAnimate<any> {
protected currentAnimationRatio = 0;
protected animationTime = 0;

constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {
super(from, to, duration, easing, params);
}

onUpdate(end: boolean, ratio: number, out: any): void {
super.onUpdate(end, ratio, out);
this.currentAnimationRatio = ratio;
this.animationTime = ratio * Math.PI * 2;
}

/**
* 获取基于动画进度的时间
*/
protected getAnimationTime(): number {
if (this.currentAnimationRatio > 0) {
return this.animationTime;
}
return Date.now() / 1000.0;
}

protected afterStageRender(stage: any, canvas: HTMLCanvasElement): void {
this.params?.callBack?.(stage, canvas, this.currentAnimationRatio, this.animationTime);
}
}
41 changes: 7 additions & 34 deletions packages/vchart/src/animation/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,16 @@ import {
GrowPointsYOut,
ClipIn,
ClipOut,
FromTo,
Dissolve,
Grayscale,
Distortion,
Particle,
Glitch,
GaussianBlur,
Pixelation
FromTo
} from '@visactor/vrender-animate';

import type { ILineAnimationParams, LineAppearPreset } from '../series/line/interface';
import { linePresetAnimation } from '../series/line/animation';
import type { MarkAnimationSpec, ICartesianGroupAnimationParams } from './interface';
import { Factory } from '../core/factory';
import { Direction } from '../typings/space';
import { CallbackDisappearAnimate } from './callback-disappear';
import { BuiltIn_DISAPPEAR_ANIMATE_NAME } from '../constant/animate';

export const DEFAULT_ANIMATION_CONFIG = {
appear: {
Expand Down Expand Up @@ -79,15 +74,13 @@ export const DEFAULT_ANIMATION_CONFIG = {
export const ScaleInOutAnimation = {
appear: { type: 'scaleIn' },
enter: { type: 'scaleIn' },
exit: { type: 'scaleOut' },
disappear: { type: 'scaleOut' }
exit: { type: 'scaleOut' }
};

export const FadeInOutAnimation = {
appear: { type: 'fadeIn' },
enter: { type: 'fadeIn' },
exit: { type: 'fadeOut' },
disappear: { type: 'fadeOut' }
exit: { type: 'fadeOut' }
};

export const registerScaleInOutAnimation = () => {
Expand All @@ -113,19 +106,6 @@ export const registerCartesianGroupClipAnimation = () => {
orient: params.orient()
};
}
},
disappear: {
custom: ClipDirectionAnimate,
customParameters: (datum: any, g: IGraphic) => {
return {
animationType: 'out',
group: g,
direction: params.direction(),
width: params.width(),
height: params.height(),
orient: params.orient()
};
}
}
};
});
Expand All @@ -150,8 +130,7 @@ const lineOrAreaAnimation = (params: ILineAnimationParams, preset: LineAppearPre
clipRangeByDimension: params.direction === Direction.horizontal ? 'y' : 'x'
}
}
],
disappear: { type: 'clipOut' }
]
} as MarkAnimationSpec;
};

Expand Down Expand Up @@ -209,11 +188,5 @@ export const registerPolygonAnimation = () => {
};

export const registerStageAnimation = () => {
AnimateExecutor.registerBuiltInAnimate('distortion', Distortion);
AnimateExecutor.registerBuiltInAnimate('particle', Particle);
AnimateExecutor.registerBuiltInAnimate('pixelation', Pixelation);
AnimateExecutor.registerBuiltInAnimate('gaussianBlur', GaussianBlur);
AnimateExecutor.registerBuiltInAnimate('glitch', Glitch);
AnimateExecutor.registerBuiltInAnimate('grayscale', Grayscale);
AnimateExecutor.registerBuiltInAnimate('dissolve', Dissolve);
AnimateExecutor.registerBuiltInAnimate(BuiltIn_DISAPPEAR_ANIMATE_NAME, CallbackDisappearAnimate);
};
10 changes: 7 additions & 3 deletions packages/vchart/src/animation/interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ACustomAnimate } from '@visactor/vrender-animate';
import type { IGraphic, EasingType } from '@visactor/vrender-core';
import type { ACustomAnimate, AStageAnimate } from '@visactor/vrender-animate';
import type { IGraphic, EasingType, IStage } from '@visactor/vrender-core';
import type { IMark, IMarkGraphic } from '../mark/interface/common';
import type { BaseMark } from '../mark';

Expand Down Expand Up @@ -159,8 +159,12 @@ export interface IAnimationTimeline {

export type IAnimationConfig = IAnimationTimeline | IAnimationTypeConfig;

export type IStageAnimationCallback = (stage: IStage, canvas: HTMLCanvasElement, ratio: number, time: number) => void;

export interface MarkAnimationSpec {
disappear?: IAnimationConfig | IAnimationConfig[];
disappear?: IStateAnimationConfig & {
callBack?: IStageAnimationCallback | AStageAnimate<any>;
};
appear?: IAnimationConfig | IAnimationConfig[];
enter?: IAnimationConfig | IAnimationConfig[];
exit?: IAnimationConfig | IAnimationConfig[];
Expand Down
17 changes: 17 additions & 0 deletions packages/vchart/src/chart/base/base-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import type { IMorphConfig } from '../../animation/spec';
import { Interaction } from '../../interaction/interaction';
import type { IInteraction } from '../../interaction/interface/common';
import type { IBaseTriggerOptions } from '../../interaction/interface/trigger';
import { animationConfig, userAnimationConfig } from '../../animation/utils';

export class BaseChart<T extends IChartSpec> extends CompilableBase implements IChart {
readonly type: string = 'chart';
Expand Down Expand Up @@ -313,6 +314,22 @@ export class BaseChart<T extends IChartSpec> extends CompilableBase implements I
this.reDataFlow();

this._initInteractions();

this.initStageAnimation();
}

initStageAnimation() {
const compiler = this._option.getCompiler();
if (!compiler?.setStageAnimationConfig) {
return;
}
compiler.setStageAnimationConfig(
animationConfig(
{}, // Factory.getAnimationInKey('stage')?.({}, null),
userAnimationConfig('stage', this._spec as any, {}),
null
)
);
}

reDataFlow() {
Expand Down
74 changes: 33 additions & 41 deletions packages/vchart/src/compile/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { CompilerListenerParameters, ICompiler, IRenderContainer, IRenderOp
// eslint-disable-next-line no-duplicate-imports
import { LayoutState } from './interface';
import { isMobileLikeMode, isTrueBrowser } from '../util/env';
import { isString } from '../util/type';
import { isClass, isString } from '../util/type';
import type { IBoundsLike } from '@visactor/vutils';
// eslint-disable-next-line no-duplicate-imports
import { array, isArray, isObject, isValid } from '@visactor/vutils';
Expand All @@ -22,6 +22,7 @@ import { diffMarks, findSimpleMarks, toRenderMode, traverseGroupMark } from './u
import { log } from '../util/debug';
import type { MarkAnimationSpec, TypeAnimationConfig } from '../animation/interface';
import { AnimationStateEnum } from '../animation/interface';
import { BuiltIn_DISAPPEAR_ANIMATE_NAME } from '../constant/animate';

type EventListener = {
type: string;
Expand All @@ -47,6 +48,9 @@ export class Compiler implements ICompiler {
protected _stage: IStage;

protected _stateAnimationConfig: Partial<MarkAnimationSpec>;
get stateAnimationConfig() {
return this._stateAnimationConfig;
}

protected _rootGroup: IGroup;

Expand Down Expand Up @@ -312,7 +316,6 @@ export class Compiler implements ICompiler {
private _doRender(immediately: boolean) {
this._option.performanceHook?.beforeDoRender?.(this._compileChart.getOption().globalInstance);
if (this._stage) {
this.runStageAnimation();
this._rootMarks.forEach(g => {
traverseGroupMark(
g,
Expand Down Expand Up @@ -444,19 +447,37 @@ export class Compiler implements ICompiler {
Object.keys(config).forEach(key => {
const value = (config as any)[key];
if (isArray(value)) {
(animationConfig as any)[key] = value.map(item => {
const options = item!.options ?? {};

return {
...item,
options: (...args: any[]) => {
const _options = typeof options === 'function' ? options(...args) : options;
if (key === 'disappear') {
(animationConfig as any)[key] = value.map(item => {
if (isClass(item.callBack)) {
return {
..._options
...item,
custom: item.callBack
};
}
};
});
return {
...item,
type: BuiltIn_DISAPPEAR_ANIMATE_NAME,
customParameters: {
callBack: item.callBack
}
};
});
} else {
(animationConfig as any)[key] = value.map(item => {
const options = item!.options ?? {};

return {
...item,
options: (...args: any[]) => {
const _options = typeof options === 'function' ? options(...args) : options;
return {
..._options
};
}
};
});
}
} else {
(animationConfig as any)[key] = {
...(config as any)[key]
Expand Down Expand Up @@ -485,35 +506,6 @@ export class Compiler implements ICompiler {
this._stage.context.animationState = animationState;
}

runStageAnimation() {
const animationState: AnimationStateValues = this._stage.context?.animationState;
if (!this._stateAnimationConfig || animationState === AnimationStateEnum.none) {
return;
}
const animationConfigs = array(this._stateAnimationConfig[animationState]).filter(
config => (config as TypeAnimationConfig).type
);
if (!animationConfigs.length) {
return;
}
// clear last animation
if (animationState === AnimationStateEnum.appear) {
this._stage.stopAnimationState(AnimationStateEnum.disappear);
} else if (animationState === AnimationStateEnum.disappear) {
this._stage.stopAnimationState(AnimationStateEnum.appear);
}
// apply current animation
this._stage.applyAnimationState(
[animationState],
[
{
name: animationState,
animation: animationConfigs
}
]
);
}

updateViewBox(viewBox: IBoundsLike, reRender: boolean = true) {
if (!this._stage) {
return;
Expand Down
1 change: 1 addition & 0 deletions packages/vchart/src/compile/interface/compilable-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type ICompilerModel = Record<GrammarType, IProductMap<IGrammarItem>>;

export interface ICompiler {
isInited?: boolean;
readonly stateAnimationConfig?: MarkAnimationSpec;
getCanvas: () => HTMLCanvasElement | undefined;
getStage: () => IStage | undefined;
compile: (ctx: { chart: IChart; vChart: IVChart }, option?: IVChartRenderOption) => void;
Expand Down
8 changes: 8 additions & 0 deletions packages/vchart/src/constant/animate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { PREFIX } from '../core';

export const BuiltIn_DISAPPEAR_ANIMATE_NAME = `${PREFIX}_BuiltIn_CallBack_Disappear`;

export enum RenderStateEnum {
render = 'render',
disappear = 'disappear'
}
26 changes: 26 additions & 0 deletions packages/vchart/src/core/vchart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import { registerElementHighlight } from '../interaction/triggers/element-highli
import { registerElementSelect } from '../interaction/triggers/element-select';
import type { IVChartPluginService } from '../plugin/vchart/interface';
import { VChartPluginService } from '../plugin/vchart/plugin-service';
import { RenderStateEnum } from '../constant/animate';

export class VChart implements IVChart {
readonly id = createID();
Expand Down Expand Up @@ -366,6 +367,8 @@ export class VChart implements IVChart {

private _onResize?: () => void;

private _renderState: RenderStateEnum = RenderStateEnum.render;

constructor(spec: ISpec, options: IInitOption) {
removeUndefined(options);
this._option = {
Expand Down Expand Up @@ -940,6 +943,7 @@ export class VChart implements IVChart {
parserOptions?: IParserOptions,
userUpdateOptions?: IUpdateDataResult
) {
this._reSetRenderState();
if (isNil(this._dataSet)) {
return this as unknown as IVChart;
}
Expand Down Expand Up @@ -971,6 +975,7 @@ export class VChart implements IVChart {
reRender: boolean = true,
userUpdateOptions?: IUpdateSpecResult
) {
this._reSetRenderState();
if (this._chart) {
this._chart.updateFullData(data);
if (reRender) {
Expand Down Expand Up @@ -1087,6 +1092,8 @@ export class VChart implements IVChart {
forceMerge: boolean = false,
userUpdateOptions?: IUpdateSpecResult
): IUpdateSpecResult | undefined => {
this._reSetRenderState();

const lastSpec = this._spec;

const result: IUpdateSpecResult = {
Expand Down Expand Up @@ -2251,6 +2258,25 @@ export class VChart implements IVChart {
componentShowContent: this._option.componentShowContent
};
}

public runDisappearAnimation() {
this._renderState = RenderStateEnum.disappear;
this.getStage().eventSystem.pauseTriggerEvent();
this.getStage().applyAnimationState(
['disappear'],
[
{
name: 'disappear',
animation: this._compiler.stateAnimationConfig.disappear
}
]
);
}

private _reSetRenderState() {
this._renderState = RenderStateEnum.render;
this.getStage().eventSystem.resumeTriggerEvent();
}
}

export const registerVChartCore = () => {
Expand Down
Loading
Loading