Skip to content

Commit

Permalink
feat: support table animate
Browse files Browse the repository at this point in the history
  • Loading branch information
neuqzxy committed Dec 27, 2024
1 parent 1c833ed commit 6f94199
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vstory-core",
"comment": "feat: support table animate",
"type": "none"
}
],
"packageName": "@visactor/vstory-core"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vstory-player",
"comment": "feat: support table animate",
"type": "none"
}
],
"packageName": "@visactor/vstory-player"
}
69 changes: 65 additions & 4 deletions packages/vstory-core/src/character/table/character-table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ITicker, ITimeline } from '@visactor/vrender-core';
import type { IGroup, ITicker, ITimeline } from '@visactor/vrender-core';
import { DefaultTimeline, ManualTicker } from '@visactor/vrender-core';
import type { ICharacterPickInfo, IStoryEvent } from '../../interface/event';
import { CharacterBase } from '../character-base';
Expand All @@ -16,6 +16,7 @@ import { TableTypeRuntimeInstance } from './runtime/table-type';
import { CellStyleRuntimeInstance } from './runtime/cell-style';
import { ColWidthRuntimeInstance } from './runtime/col-width';
import { RowHeightRuntimeInstance } from './runtime/row-height';
import { isArray } from '@visactor/vutils';

export class CharacterTable<T extends ITableGraphicAttribute>
extends CharacterBase<ITableGraphicAttribute>
Expand Down Expand Up @@ -49,13 +50,73 @@ export class CharacterTable<T extends ITableGraphicAttribute>
}

getGraphicBySelector(selector: string | string[]) {
const table = true;
let table = false;
let panel = false;
if (isArray(selector)) {
selector.forEach(s => {
const data = this._getGraphicBySelector(s);
table = table || data.table;
panel = panel || data.panel;
});
return {
table,
panel
};
}
return this._getGraphicBySelector(selector);
}

_getGraphicBySelector(selector: string) {
const vtable = this._graphic.vTable;
let table = false;
// 是否包含panel, >0为包含
const includePanel = 1;
let includePanel = 1;
const rowHeader = vtable.scenegraph.rowHeaderGroup;
const colHeader = vtable.scenegraph.colHeaderGroup;
const bodyGroup = vtable.scenegraph.bodyGroup;

let out: any = {
rowHeader,
colHeader,
bodyGroup
};

const selectorList = selector.split(' ');
selectorList.forEach(subSelector => {
if (subSelector === '*') {
table = true;
} else if (/:not\(([^)]+)\)/.test(subSelector)) {
const match = /:not\(([^)]+)\)/.exec(subSelector)[1];
out = this.selectByType(out, match, false);
if (match === 'panel') {
includePanel = -Infinity; // 如果被排除,那么一定不包含了
}
} else {
out = this.selectByType(out, subSelector);
if (subSelector === 'panel') {
includePanel = Infinity; // 如果有正选,那么选中才算
} else {
includePanel--;
}
}
});

return {
table,
panel: includePanel > 0
panel: includePanel > 0,
...out
};
}

protected selectByType(
data: { rowHeader: IGroup; colHeader: IGroup; bodyGroup: IGroup },
name: string,
match: boolean = true
) {
return {
rowHeader: (name === 'rowHeader') === match ? data.rowHeader : null,
colHeader: (name === 'colHeader') === match ? data.colHeader : null,
bodyGroup: (name === 'body') === match ? data.bodyGroup : null
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ export class FadeVisibility {
} as any);
}
}
run(graphic: IGraphic, params: IFadeInParams, appear: boolean) {
run(graphic: IGraphic, params: IFadeInParams, appear: boolean, setInitAttributes: boolean = false) {
if (!canDoGraphicAnimation(graphic, params)) {
return false;
}
setInitAttributes && this.setInitAttributes(graphic, params, appear);
const duration = params.duration;
const easing = params.easing;

Expand Down
12 changes: 5 additions & 7 deletions packages/vstory-player/src/processor/common/move-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export class MoveVisibility {
y: fromY
});
}
run(graphic: IGraphic, params: IMoveParams, appear: boolean) {
run(graphic: IGraphic, params: IMoveParams, appear: boolean, setInitAttributes: boolean = false) {
if (!canDoGraphicAnimation(graphic, params)) {
return false;
}
setInitAttributes && this.setInitAttributes(graphic, params, appear);
return appear ? this._moveIn(graphic, params) : this._moveOut(graphic, params);
}

Expand Down Expand Up @@ -119,9 +123,6 @@ export class MoveVisibility {
}

_moveIn(graphic: IGraphic, params: IMoveParams) {
if (!canDoGraphicAnimation(graphic, params)) {
return false;
}
const duration = params.duration;
const easing = params.easing;

Expand All @@ -133,9 +134,6 @@ export class MoveVisibility {
}

_moveOut(graphic: IGraphic, params: IMoveParams) {
if (!canDoGraphicAnimation(graphic, params)) {
return false;
}
const { move = {} } = params;
const to = move.pos ?? params.pos;
const duration = move.duration ?? params.duration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ export class ScaleVisibility {

graphic.setAttributes({ scaleX: ratio, scaleY: ratio });
}
run(graphic: IGraphic, animation: IScaleInParams, appear: boolean) {
if (!canDoGraphicAnimation(graphic, animation)) {
return false;
}
run(graphic: IGraphic, animation: IScaleInParams, appear: boolean, setInitAttributes: boolean = false) {
if (!canDoGraphicAnimation(graphic, animation)) {
return false;
}
setInitAttributes && this.setInitAttributes(graphic, animation, appear);

const duration = animation.duration;
const easing = animation.easing;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ export class WipeVisibility {
wipeRatio: fromRatio
} as any);
}
run(graphic: IGraphic, params: IWipeInParams, appear: boolean) {
run(graphic: IGraphic, params: IWipeInParams, appear: boolean, setInitAttributes: boolean = false) {
if (!canDoGraphicAnimation(graphic, params)) {
return false;
}
setInitAttributes && this.setInitAttributes(graphic, params, appear);

const duration = params.duration;
const easing = params.easing;
Expand Down
4 changes: 4 additions & 0 deletions packages/vstory-player/src/processor/table/base.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { IGroup } from '@visactor/vrender-core';
import { ActionProcessorItem } from '../processor-item';
import type { IActionSpec, ICharacter } from '@visactor/vstory-core';
import { array } from '@visactor/vutils';
Expand All @@ -14,6 +15,9 @@ export class VTableBaseActionProcessor extends ActionProcessorItem {
): {
table: boolean;
panel: boolean;
rowHeader: IGroup;
colHeader: IGroup;
bodyGroup: IGroup;
} {
return character.getGraphicBySelector(selector);
}
Expand Down
93 changes: 91 additions & 2 deletions packages/vstory-player/src/processor/table/visibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import type { IGroup } from '@visactor/vrender-core';
import { ACTION_TYPE } from '../constants/action';
import { CommonBounceActionProcessor } from '../component/common/bounce';
import { CommonStyleActionProcessor } from '../component/common/style';
import type { IVTable } from '@visactor/vstory-core/src/character/table/interface/character-table';
import { scaleInstance } from '../common/scale-processor';
import { wipeInstance } from '../common/wipe-processor';
import { fadeInstance } from '../common/fade-processor';
import { moveInstance } from '../common/move-processor';

export class VTableVisibilityActionProcessor extends VTableBaseActionProcessor {
name: 'appearOrDisAppear';
Expand All @@ -22,22 +27,106 @@ export class VTableVisibilityActionProcessor extends VTableBaseActionProcessor {
this.character = character;
// 基于选择器做筛选
// 同一个Action的payload数组中,项与项之间是覆盖关系,后项覆盖前项
const runnedTable = false;
let runnedTable = false;
array(actionSpec.payload)
.reverse()
.forEach(payload => {
const { table, panel } = this.selectBySelector(payload.selector ?? '*', character);
const { table, panel, rowHeader, colHeader, bodyGroup } = this.selectBySelector(
payload.selector ?? '*',
character
);
if (!runnedTable && table) {
// table & panel
this.tableVisibility(character.graphic as any, actionSpec.action, payload);
} else if (!runnedTable && panel) {
// panel
this.panelVisibility(character.graphic as any, actionSpec.action, payload);
}
if (rowHeader) {
this.headerAppear('row', character.graphic as any, rowHeader, actionSpec.action, payload, true);
}
if (colHeader) {
this.headerAppear('col', character.graphic as any, colHeader, actionSpec.action, payload, true);
}
if (bodyGroup) {
this.bodyGroupAppear(character.graphic as any, bodyGroup, actionSpec.action, payload, true);
}
runnedTable = runnedTable || table;
});
this.character = null;
}

protected headerAppear(
type: 'row' | 'col',
vtable: IVTable,
headerGroup: IGroup,
action: 'appear' | 'disappear',
payload: ITableVisibilityPayload,
isRun: boolean
) {
if (isRun) {
headerGroup.setAttribute('visibleAll', true);
const appear = action === 'appear';
const effectInstance = this.getEffectInstance(payload.animation?.effect as string, appear);
effectInstance.run(headerGroup, { from: type === 'col' ? 'left' : 'top', ...payload.animation }, appear, true);
} else {
headerGroup.setAttribute('visibleAll', false);
}
}

protected bodyGroupAppear(
vtable: IVTable,
bodyGroup: IGroup,
action: 'appear' | 'disappear',
payload: ITableVisibilityPayload,
isRun: boolean
) {
if (isRun) {
bodyGroup.setAttribute('visibleAll', true);
// 做默认动画
const appear = action === 'appear';
const { duration, oneByOne = true, easing } = payload.animation;
let delay = 0;
let actualDuration = duration;
if (oneByOne) {
actualDuration = duration * 0.6;
delay = (duration - actualDuration) / bodyGroup.childrenCount;
}
const from = appear ? { baseOpacity: 0 } : { baseOpacity: 1 };
const to = appear ? { baseOpacity: 1 } : { baseOpacity: 0 };
bodyGroup.forEachChildren((child, i) => {
(child as any).setAttributes(from);
(child as any)
.animate()
.wait(delay * i)
.to(to, actualDuration, easing);
});
} else {
bodyGroup.setAttribute('visibleAll', false);
}
}

getEffectInstance(effect: string, appear: boolean) {
switch (effect) {
case 'scale':
return scaleInstance;
case 'wipe':
return wipeInstance;
case 'fade':
return fadeInstance;
case 'move':
return moveInstance;
}
return fadeInstance;
}

// protected rowHeaderAppear(
// vtable: IVTable,
// rowHeader: IGroup
// ) {
// return this.headerAppear(vtable, rowHeader);
// }

protected tableVisibility(tableGraphic: any, action: 'appear' | 'disappear', payload: ITableVisibilityPayload) {
const appearTransformFunc = transformMap.appear.table;
const defaultPayload = VTableVisibilityActionProcessor.fadePayload;
Expand Down
33 changes: 33 additions & 0 deletions packages/vstory/demo/src/demos/table/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,39 @@ function loadDSL() {
flipY: true
// dy: 30,
}
},
{
action: 'appear',
payload: {
selector: 'colHeader',
animation: {
duration: 2000,
easing: 'quadOut',
effect: 'scale'
}
}
},
{
action: 'appear',
payload: {
selector: 'rowHeader',
animation: {
duration: 2000,
easing: 'quadOut',
effect: 'scale'
}
}
},
{
action: 'appear',
payload: {
selector: 'body',
animation: {
duration: 2000,
easing: 'quadOut',
effect: 'scale'
}
}
}
]
}
Expand Down

0 comments on commit 6f94199

Please sign in to comment.