Skip to content

Commit e903a7e

Browse files
feat: allow using enterDuration and exitDurationOfPrev for figure and bg enter/exit animation config
1 parent 9ea2943 commit e903a7e

File tree

7 files changed

+115
-20
lines changed

7 files changed

+115
-20
lines changed

packages/webgal/src/Core/Modules/animationFunctions.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,22 @@ export function getEnterExitAnimation(
6161
if (isBg) {
6262
duration = 1500;
6363
}
64+
duration =
65+
webgalStore.getState().stage.animationSettings.find((setting) => setting.target === target)?.enterDuration ??
66+
duration;
6467
// 走默认动画
6568
let animation: IAnimationObject | null = generateUniversalSoftInAnimationObj(realTarget ?? target, duration);
6669

6770
const transformState = webgalStore.getState().stage.effects;
6871
const targetEffect = transformState.find((effect) => effect.target === target);
6972

70-
const animarionName = WebGAL.animationManager.nextEnterAnimationName.get(target);
73+
const animarionName = webgalStore
74+
.getState()
75+
.stage.animationSettings.find((setting) => setting.target === target)?.enterAnimationName;
7176
if (animarionName && !targetEffect) {
7277
logger.debug('取代默认进入动画', target);
7378
animation = getAnimationObject(animarionName, realTarget ?? target, getAnimateDuration(animarionName), false);
7479
duration = getAnimateDuration(animarionName);
75-
// 用后重置
76-
WebGAL.animationManager.nextEnterAnimationName.delete(target);
7780
}
7881
return { duration, animation };
7982
} else {
@@ -82,15 +85,18 @@ export function getEnterExitAnimation(
8285
if (isBg) {
8386
duration = 1500;
8487
}
88+
duration =
89+
webgalStore.getState().stage.animationSettings.find((setting) => setting.target + '-off' === target)
90+
?.exitDuration ?? duration;
8591
// 走默认动画
8692
let animation: IAnimationObject | null = generateUniversalSoftOffAnimationObj(realTarget ?? target, duration);
87-
const animarionName = WebGAL.animationManager.nextExitAnimationName.get(target);
93+
const animarionName = webgalStore
94+
.getState()
95+
.stage.animationSettings.find((setting) => setting.target + '-off' === target)?.exitAnimationName;
8896
if (animarionName) {
8997
logger.debug('取代默认退出动画', target);
9098
animation = getAnimationObject(animarionName, realTarget ?? target, getAnimateDuration(animarionName), false);
9199
duration = getAnimateDuration(animarionName);
92-
// 用后重置
93-
WebGAL.animationManager.nextExitAnimationName.delete(target);
94100
}
95101
return { duration, animation };
96102
}

packages/webgal/src/Core/Modules/animations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export interface IUserAnimation {
88
export type AnimationFrame = ITransform & { duration: number; ease: string };
99

1010
export class AnimationManager {
11-
public nextEnterAnimationName: Map<string, string> = new Map();
12-
public nextExitAnimationName: Map<string, string> = new Map();
11+
// public nextEnterAnimationName: Map<string, string> = new Map();
12+
// public nextExitAnimationName: Map<string, string> = new Map();
1313
private animations: Array<IUserAnimation> = [];
1414

1515
public addAnimation(animation: IUserAnimation) {

packages/webgal/src/Core/gameScripts/changeBg/index.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export const changeBg = (sentence: ISentence): IPerform => {
2525
const series = getStringArgByKey(sentence, 'series') ?? 'default';
2626
const transformString = getStringArgByKey(sentence, 'transform');
2727
let duration = getNumberArgByKey(sentence, 'duration') ?? 1000;
28+
const enterDuration = getNumberArgByKey(sentence, 'enterDuration') ?? duration;
29+
duration = enterDuration;
30+
const exitDuration = getNumberArgByKey(sentence, 'exitDuration');
2831
const ease = getStringArgByKey(sentence, 'ease') ?? '';
2932

3033
const dispatch = webgalStore.dispatch;
@@ -42,21 +45,24 @@ export const changeBg = (sentence: ISentence): IPerform => {
4245
*/
4346
if (isUrlChanged) {
4447
dispatch(stageActions.removeEffectByTargetId(`bg-main`));
48+
dispatch(stageActions.removeAnimationSettingsByTarget(`bg-main`));
4549
}
4650

4751
// 处理 transform 和 默认 transform
4852
let animationObj: AnimationFrame[];
4953
if (transformString) {
5054
try {
5155
const frame = JSON.parse(transformString.toString()) as AnimationFrame;
52-
animationObj = generateTransformAnimationObj('bg-main', frame, duration, ease);
56+
animationObj = generateTransformAnimationObj('bg-main', frame, enterDuration, ease);
5357
// 因为是切换,必须把一开始的 alpha 改为 0
5458
animationObj[0].alpha = 0;
5559
const animationName = (Math.random() * 10).toString(16);
5660
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
5761
WebGAL.animationManager.addAnimation(newAnimation);
5862
duration = getAnimateDuration(animationName);
59-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', animationName);
63+
webgalStore.dispatch(
64+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
65+
);
6066
} catch (e) {
6167
// 解析都错误了,歇逼吧
6268
applyDefaultTransform();
@@ -75,20 +81,36 @@ export const changeBg = (sentence: ISentence): IPerform => {
7581
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
7682
WebGAL.animationManager.addAnimation(newAnimation);
7783
duration = getAnimateDuration(animationName);
78-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', animationName);
84+
webgalStore.dispatch(
85+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
86+
);
7987
}
8088

8189
// 应用动画的优先级更高一点
8290
const enterAnimation = getStringArgByKey(sentence, 'enter');
8391
const exitAnimation = getStringArgByKey(sentence, 'exit');
8492
if (enterAnimation) {
85-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', enterAnimation);
93+
webgalStore.dispatch(
94+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: enterAnimation }),
95+
);
8696
duration = getAnimateDuration(enterAnimation);
8797
}
8898
if (exitAnimation) {
89-
WebGAL.animationManager.nextExitAnimationName.set('bg-main-off', exitAnimation);
99+
webgalStore.dispatch(
100+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'exitAnimationName', value: exitAnimation }),
101+
);
90102
duration = getAnimateDuration(exitAnimation);
91103
}
104+
if (enterDuration) {
105+
webgalStore.dispatch(
106+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterDuration', value: enterDuration }),
107+
);
108+
}
109+
if (exitDuration) {
110+
webgalStore.dispatch(
111+
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'exitDuration', value: exitDuration }),
112+
);
113+
}
92114

93115
/**
94116
* 背景状态后处理

packages/webgal/src/Core/gameScripts/changeFigure.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ export function changeFigure(sentence: ISentence): IPerform {
9191
const enterAnimation = getStringArgByKey(sentence, 'enter');
9292
const exitAnimation = getStringArgByKey(sentence, 'exit');
9393
let zIndex = getNumberArgByKey(sentence, 'zIndex') ?? -1;
94+
const enterDuration = getNumberArgByKey(sentence, 'enterDuration') ?? duration;
95+
duration = enterDuration;
96+
const exitDuration = getNumberArgByKey(sentence, 'exitDurationOfPrev');
9497

9598
const dispatch = webgalStore.dispatch;
9699

@@ -145,6 +148,7 @@ export function changeFigure(sentence: ISentence): IPerform {
145148
*/
146149
if (isUrlChanged) {
147150
webgalStore.dispatch(stageActions.removeEffectByTargetId(id));
151+
webgalStore.dispatch(stageActions.removeAnimationSettingsByTarget(id));
148152
const oldStageObject = WebGAL.gameplay.pixiStage?.getStageObjByKey(id);
149153
if (oldStageObject) {
150154
oldStageObject.isExiting = true;
@@ -164,7 +168,9 @@ export function changeFigure(sentence: ISentence): IPerform {
164168
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
165169
WebGAL.animationManager.addAnimation(newAnimation);
166170
duration = getAnimateDuration(animationName);
167-
WebGAL.animationManager.nextEnterAnimationName.set(key, animationName);
171+
webgalStore.dispatch(
172+
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
173+
);
168174
} catch (e) {
169175
// 解析都错误了,歇逼吧
170176
applyDefaultTransform();
@@ -183,17 +189,33 @@ export function changeFigure(sentence: ISentence): IPerform {
183189
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
184190
WebGAL.animationManager.addAnimation(newAnimation);
185191
duration = getAnimateDuration(animationName);
186-
WebGAL.animationManager.nextEnterAnimationName.set(key, animationName);
192+
webgalStore.dispatch(
193+
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
194+
);
187195
}
188196

189197
if (enterAnimation) {
190-
WebGAL.animationManager.nextEnterAnimationName.set(key, enterAnimation);
198+
webgalStore.dispatch(
199+
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: enterAnimation }),
200+
);
191201
duration = getAnimateDuration(enterAnimation);
192202
}
193203
if (exitAnimation) {
194-
WebGAL.animationManager.nextExitAnimationName.set(key + '-off', exitAnimation);
204+
webgalStore.dispatch(
205+
stageActions.updateAnimationSettings({ target: key, key: 'exitAnimationName', value: exitAnimation }),
206+
);
195207
duration = getAnimateDuration(exitAnimation);
196208
}
209+
if (enterDuration) {
210+
webgalStore.dispatch(
211+
stageActions.updateAnimationSettings({ target: key, key: 'enterDuration', value: enterDuration }),
212+
);
213+
}
214+
if (exitDuration) {
215+
webgalStore.dispatch(
216+
stageActions.updateAnimationSettings({ target: key, key: 'exitDuration', value: exitDuration }),
217+
);
218+
}
197219
};
198220

199221
function postFigureStateSet() {

packages/webgal/src/Core/gameScripts/setTransition.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { IPerform } from '@/Core/Modules/perform/performInterface';
33
import { webgalStore } from '@/store/store';
44
import cloneDeep from 'lodash/cloneDeep';
55
import { getStringArgByKey } from '@/Core/util/getSentenceArg';
6-
import { setStage } from '@/store/stageReducer';
6+
import { setStage, stageActions } from '@/store/stageReducer';
77
import { WebGAL } from '@/Core/WebGAL';
88

99
/**
@@ -16,10 +16,14 @@ export const setTransition = (sentence: ISentence): IPerform => {
1616
const enterAnimation = getStringArgByKey(sentence, 'enter');
1717
const exitAnimation = getStringArgByKey(sentence, 'exit');
1818
if (enterAnimation) {
19-
WebGAL.animationManager.nextEnterAnimationName.set(key, enterAnimation);
19+
webgalStore.dispatch(
20+
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: enterAnimation }),
21+
);
2022
}
2123
if (exitAnimation) {
22-
WebGAL.animationManager.nextExitAnimationName.set(key + '-off', exitAnimation);
24+
webgalStore.dispatch(
25+
stageActions.updateAnimationSettings({ target: key, key: 'exitAnimationName', value: exitAnimation }),
26+
);
2327
}
2428
return {
2529
performName: 'none',

packages/webgal/src/store/stageInterface.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ export interface IEffect {
7171
transform?: ITransform; // 变换
7272
}
7373

74+
export interface IStageAnimationSetting {
75+
target: string;
76+
enterAnimationName?: string;
77+
exitAnimationName?: string;
78+
enterDuration?: number;
79+
exitDuration?: number;
80+
}
81+
82+
export type StageAnimationSettingUpdatableKey = Exclude<keyof IStageAnimationSetting, 'target'>;
83+
84+
export interface IUpdateAnimationSettingPayload {
85+
target: string;
86+
key: StageAnimationSettingUpdatableKey;
87+
value: IStageAnimationSetting[StageAnimationSettingUpdatableKey];
88+
}
89+
7490
/**
7591
* 基本变换预设
7692
*/
@@ -203,6 +219,7 @@ export interface IStageState {
203219
miniAvatar: string; // 小头像 文件地址(相对或绝对)
204220
GameVar: IGameVar; // 游戏内变量
205221
effects: Array<IEffect>; // 应用的变换
222+
animationSettings: Array<IStageAnimationSetting>;
206223
bgTransform: string;
207224
bgFilter: string;
208225
PerformList: Array<IRunPerform>; // 要启动的演出列表

packages/webgal/src/store/stageReducer.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import {
1515
IRunPerform,
1616
ISetGameVar,
1717
ISetStagePayload,
18+
IStageAnimationSetting,
1819
IStageState,
20+
IUpdateAnimationSettingPayload,
1921
} from '@/store/stageInterface';
2022
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
2123
import cloneDeep from 'lodash/cloneDeep';
@@ -56,6 +58,7 @@ export const initState: IStageState = {
5658
transform: baseTransform,
5759
},
5860
],
61+
animationSettings: [],
5962
bgFilter: '', // 现在不用,先预留
6063
bgTransform: '', // 现在不用,先预留
6164
PerformList: [], // 要启动的演出列表
@@ -135,6 +138,27 @@ const stageSlice = createSlice({
135138
state.effects.splice(index, 1);
136139
}
137140
},
141+
updateAnimationSettings: (state, action: PayloadAction<IUpdateAnimationSettingPayload>) => {
142+
const { target, key, value } = action.payload;
143+
const animationIndex = state.animationSettings.findIndex((a) => a.target === target);
144+
if (animationIndex >= 0) {
145+
state.animationSettings[animationIndex] = {
146+
...state.animationSettings[animationIndex],
147+
[key]: value,
148+
};
149+
} else {
150+
state.animationSettings.push({
151+
target,
152+
[key]: value,
153+
});
154+
}
155+
},
156+
removeAnimationSettingsByTarget: (state, action: PayloadAction<string>) => {
157+
const index = state.animationSettings.findIndex((a) => a.target === action.payload);
158+
if (index >= 0) {
159+
state.animationSettings.splice(index, 1);
160+
}
161+
},
138162
addPerform: (state, action: PayloadAction<IRunPerform>) => {
139163
// 先检查是否有重复的,全部干掉
140164
const dupPerformIndex = state.PerformList.findIndex((p) => p.id === action.payload.id);

0 commit comments

Comments
 (0)