Skip to content

Commit 66963a4

Browse files
author
Hardy--Lee
committed
fix: changeFigure and changeBg duration
1 parent 4a4bf80 commit 66963a4

File tree

8 files changed

+182
-114
lines changed

8 files changed

+182
-114
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { baseTransform } from '@/store/stageInterface';
77
import { generateTimelineObj } from '@/Core/controller/stage/pixi/animations/timeline';
88
import { WebGAL } from '@/Core/WebGAL';
99
import PixiStage, { IAnimationObject } from '@/Core/controller/stage/pixi/PixiController';
10+
import { AnimationFrame, IUserAnimation } from './animations';
11+
import { generateTransformAnimationObj } from '../controller/stage/pixi/animations/generateTransformAnimationObj';
1012

1113
// eslint-disable-next-line max-params
1214
export function getAnimationObject(animationName: string, target: string, duration: number, writeDefault: boolean) {
@@ -89,3 +91,23 @@ export function getEnterExitAnimation(
8991
return { duration, animation };
9092
}
9193
}
94+
95+
export function createDefaultEnterExitAnimation(type: 'enter' | 'exit', target: string, frame: AnimationFrame, duration: number, ease: string) {
96+
if (type === 'enter') {
97+
// 设置默认入场动画
98+
const enterAnimationObj = generateTransformAnimationObj(target, frame, duration, ease, 'enter');
99+
const enterAnimationName = (Math.random() * 10).toString(16);
100+
const newEnterAnimation: IUserAnimation = { name: enterAnimationName, effects: enterAnimationObj };
101+
WebGAL.animationManager.addAnimation(newEnterAnimation);
102+
duration = getAnimateDuration(enterAnimationName);
103+
WebGAL.animationManager.nextEnterAnimationName.set(target, enterAnimationName);
104+
} else {
105+
// 设置默认退场动画
106+
const exitAnimationObj = generateTransformAnimationObj(target, frame, duration, ease, 'exit');
107+
const exitAnimationName = (Math.random() * 10).toString(16);
108+
const newExitAnimation: IUserAnimation = { name: exitAnimationName, effects: exitAnimationObj };
109+
WebGAL.animationManager.addAnimation(newExitAnimation);
110+
duration = getAnimateDuration(exitAnimationName);
111+
WebGAL.animationManager.nextExitAnimationName.set(target + '-off', exitAnimationName);
112+
}
113+
}

packages/webgal/src/Core/controller/stage/pixi/PixiController.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface IStageAnimationObject {
2828
targetKey?: string;
2929
type: 'common' | 'preset';
3030
animationObject: IAnimationObject;
31+
stopFunction?: () => void;
3132
}
3233

3334
export interface IStageObject {
@@ -212,6 +213,7 @@ export default class PixiStage {
212213
key: string,
213214
target = 'default',
214215
currentEffects: IEffect[],
216+
stopFunction: () => void,
215217
) {
216218
if (!animationObject) return;
217219
const effect = currentEffects.find((effect) => effect.target === target);
@@ -223,7 +225,7 @@ export default class PixiStage {
223225
}
224226
return;
225227
}
226-
this.stageAnimations.push({ uuid: uuid(), animationObject, key: key, targetKey: target, type: 'preset' });
228+
this.stageAnimations.push({ uuid: uuid(), animationObject, key: key, targetKey: target, type: 'preset', stopFunction });
227229
// 上锁
228230
this.lockStageObject(target);
229231
animationObject.setStartState();
@@ -247,6 +249,7 @@ export default class PixiStage {
247249
const thisTickerFunc = this.stageAnimations[index];
248250
this.currentApp?.ticker.remove(thisTickerFunc.animationObject.tickerFunc);
249251
thisTickerFunc.animationObject.setEndState();
252+
thisTickerFunc.stopFunction?.();
250253
this.unlockStageObject(thisTickerFunc.targetKey ?? 'default');
251254
this.stageAnimations.splice(index, 1);
252255
}

packages/webgal/src/Core/controller/stage/pixi/animations/generateTransformAnimationObj.ts

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,48 @@ type AnimationObj = Array<AnimationFrame>;
88
export function generateTransformAnimationObj(
99
target: string,
1010
applyFrame: AnimationFrame,
11-
duration: number | string | boolean | null,
11+
duration: number,
1212
ease: string,
13+
type: 'enter' | 'exit' | 'normal',
1314
): AnimationObj {
14-
let animationObj;
15+
let animationObj: AnimationFrame[] = [];
1516
// 获取那个 target 的当前变换
1617
const transformState = webgalStore.getState().stage.effects;
1718
const targetEffect = transformState.find((effect) => effect.target === target);
1819

19-
applyFrame.duration = 500;
20-
if (!isNull(duration) && typeof duration === 'number') {
21-
applyFrame.duration = duration;
20+
switch (type) {
21+
case 'normal': {
22+
if (targetEffect) {
23+
// 找到存在的 effect 时, 将该 effect 作为起始状态
24+
const effectWithDuration = { ...targetEffect!.transform!, duration: 0, ease };
25+
applyFrame = { ...applyFrame, duration, ease };
26+
animationObj.push(effectWithDuration);
27+
animationObj.push(applyFrame);
28+
break;
29+
} else {
30+
// 找不到 effect 时, 作为 enter 动画考虑
31+
type = 'enter';
32+
// 不加 break, 继续执行接下来的 case
33+
}
34+
}
35+
case 'enter': {
36+
// 在最开头加上 applyFrame 的 alpha 0 版本, 实现透明度淡入动画
37+
const effectWithDuration = { ...applyFrame, alpha: 0, duration: 0, ease };
38+
applyFrame = { ...applyFrame, duration, ease };
39+
animationObj.push(effectWithDuration);
40+
animationObj.push(applyFrame);
41+
break;
42+
}
43+
case 'exit': {
44+
// 在最末尾加上 applyFrame 的 alpha 0 版本, 实现透明度淡出动画
45+
// 按理说应该拿 targetEffect 才对, 但是退场动画在调用这个函数前
46+
// 就已经把 effect 清掉了, 故需要手动传进来
47+
applyFrame = { ...applyFrame, duration: 0, ease };
48+
const effectWithDuration = { ...applyFrame, alpha: 0, duration, ease };
49+
animationObj.push(applyFrame);
50+
animationObj.push(effectWithDuration);
51+
}
2252
}
23-
applyFrame.ease = ease;
24-
animationObj = [applyFrame];
2553

26-
// 找到 effect
27-
if (targetEffect) {
28-
const effectWithDuration = { ...targetEffect!.transform!, duration: 0, ease };
29-
animationObj.unshift(effectWithDuration);
30-
} else {
31-
// 应用默认effect,也就是最终的 effect 的 alpha = 0 版本
32-
const effectWithDuration = { ...applyFrame, alpha: 0, duration: 0, ease };
33-
animationObj.unshift(effectWithDuration);
34-
}
3554
return animationObj;
3655
}

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

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { setStage, stageActions } from '@/store/stageReducer';
77
import { getSentenceArgByKey } from '@/Core/util/getSentenceArg';
88
import { unlockCgInUserData } from '@/store/userDataReducer';
99
import { logger } from '@/Core/util/logger';
10-
import { ITransform } from '@/store/stageInterface';
10+
import { baseTransform, ITransform } from '@/store/stageInterface';
1111
import { generateTransformAnimationObj } from '@/Core/controller/stage/pixi/animations/generateTransformAnimationObj';
1212
import { AnimationFrame, IUserAnimation } from '@/Core/Modules/animations';
1313
import cloneDeep from 'lodash/cloneDeep';
14-
import { getAnimateDuration } from '@/Core/Modules/animationFunctions';
14+
import { createDefaultEnterExitAnimation, getAnimateDuration } from '@/Core/Modules/animationFunctions';
1515
import { WebGAL } from '@/Core/WebGAL';
1616

1717
/**
@@ -21,6 +21,7 @@ import { WebGAL } from '@/Core/WebGAL';
2121
*/
2222
export const changeBg = (sentence: ISentence): IPerform => {
2323
const url = sentence.content;
24+
const key = 'bg-main';
2425
let name = '';
2526
let series = 'default';
2627
sentence.args.forEach((e) => {
@@ -35,10 +36,18 @@ export const changeBg = (sentence: ISentence): IPerform => {
3536
const dispatch = webgalStore.dispatch;
3637
if (name !== '') dispatch(unlockCgInUserData({ name, url, series }));
3738

39+
40+
// 储存一下现有的 transform 给退场动画当起始帧用, 因为马上就要清除了
41+
const currentEffect = webgalStore.getState().stage.effects.find((e) => e.target === key);
42+
let currentTransform = baseTransform;
43+
if (currentEffect && currentEffect.transform) {
44+
currentTransform = currentEffect.transform;
45+
}
46+
3847
/**
3948
* 删掉相关 Effects,因为已经移除了
4049
*/
41-
dispatch(stageActions.removeEffectByTargetId(`bg-main`));
50+
dispatch(stageActions.removeEffectByTargetId(key));
4251

4352
// 处理 transform 和 默认 transform
4453
const transformString = getSentenceArgByKey(sentence, 'transform');
@@ -49,54 +58,45 @@ export const changeBg = (sentence: ISentence): IPerform => {
4958
}
5059
let animationObj: AnimationFrame[];
5160
if (transformString) {
61+
console.log(transformString);
5262
try {
53-
const frame = JSON.parse(transformString.toString()) as AnimationFrame;
54-
animationObj = generateTransformAnimationObj('bg-main', frame, duration, ease);
55-
// 因为是切换,必须把一开始的 alpha 改为 0
56-
animationObj[0].alpha = 0;
57-
const animationName = (Math.random() * 10).toString(16);
58-
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
59-
WebGAL.animationManager.addAnimation(newAnimation);
60-
duration = getAnimateDuration(animationName);
61-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', animationName);
63+
const transform = JSON.parse(transformString.toString()) as ITransform;
64+
const enterFrame = {...transform, duration: 0, ease: ''};
65+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
66+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
67+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
6268
} catch (e) {
6369
// 解析都错误了,歇逼吧
64-
applyDefaultTransform();
70+
const enterFrame = {...baseTransform, duration: 0, ease: ''};
71+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
72+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
73+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
6574
}
6675
} else {
67-
applyDefaultTransform();
68-
}
69-
70-
function applyDefaultTransform() {
71-
// 应用默认的
72-
const frame = {};
73-
animationObj = generateTransformAnimationObj('bg-main', frame as AnimationFrame, duration, ease);
74-
// 因为是切换,必须把一开始的 alpha 改为 0
75-
animationObj[0].alpha = 0;
76-
const animationName = (Math.random() * 10).toString(16);
77-
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
78-
WebGAL.animationManager.addAnimation(newAnimation);
79-
duration = getAnimateDuration(animationName);
80-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', animationName);
76+
const enterFrame = {...baseTransform, duration: 0, ease: ''};
77+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
78+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
79+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
8180
}
8281

8382
// 应用动画的优先级更高一点
8483
if (getSentenceArgByKey(sentence, 'enter')) {
85-
WebGAL.animationManager.nextEnterAnimationName.set('bg-main', getSentenceArgByKey(sentence, 'enter')!.toString());
84+
WebGAL.animationManager.nextEnterAnimationName.set(key, getSentenceArgByKey(sentence, 'enter')!.toString());
8685
duration = getAnimateDuration(getSentenceArgByKey(sentence, 'enter')!.toString());
8786
}
8887
if (getSentenceArgByKey(sentence, 'exit')) {
89-
WebGAL.animationManager.nextExitAnimationName.set('bg-main-off', getSentenceArgByKey(sentence, 'exit')!.toString());
88+
WebGAL.animationManager.nextExitAnimationName.set(key + '-off', getSentenceArgByKey(sentence, 'exit')!.toString());
9089
duration = getAnimateDuration(getSentenceArgByKey(sentence, 'exit')!.toString());
9190
}
9291
dispatch(setStage({ key: 'bgName', value: sentence.content }));
9392

9493
return {
95-
performName: `bg-main-${sentence.content}`,
94+
performName: `${key}-${sentence.content}`,
9695
duration,
9796
isHoldOn: false,
9897
stopFunction: () => {
99-
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget('bg-main');
98+
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key);
99+
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key + '-old' + '-off');
100100
},
101101
blockingNext: () => false,
102102
blockingAuto: () => true,

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

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import { webgalStore } from '@/store/store';
44
import { setStage, stageActions } from '@/store/stageReducer';
55
import cloneDeep from 'lodash/cloneDeep';
66
import { getSentenceArgByKey } from '@/Core/util/getSentenceArg';
7-
import { IFreeFigure, IStageState, ITransform } from '@/store/stageInterface';
7+
import { baseTransform, IFreeFigure, IStageState, ITransform } from '@/store/stageInterface';
88
import { AnimationFrame, IUserAnimation } from '@/Core/Modules/animations';
99
import { generateTransformAnimationObj } from '@/Core/controller/stage/pixi/animations/generateTransformAnimationObj';
1010
import { assetSetter, fileType } from '@/Core/util/gameAssetsAccess/assetSetter';
1111
import { logger } from '@/Core/util/logger';
12-
import { getAnimateDuration } from '@/Core/Modules/animationFunctions';
12+
import { createDefaultEnterExitAnimation, getAnimateDuration } from '@/Core/Modules/animationFunctions';
1313
import { WebGAL } from '@/Core/WebGAL';
1414
/**
1515
* 更改立绘
@@ -153,6 +153,24 @@ export function changeFigure(sentence: ISentence): IPerform {
153153
}
154154
}
155155
}
156+
157+
// 确定 key
158+
if (!isFreeFigure) {
159+
const positionMap = {
160+
center: 'fig-center',
161+
left: 'fig-left',
162+
right: 'fig-right',
163+
};
164+
key = positionMap[pos];
165+
}
166+
167+
// 储存一下现有的 transform 给退场动画当起始帧用, 因为马上就要清除了
168+
const currentEffect = webgalStore.getState().stage.effects.find((e) => e.target === key);
169+
let currentTransform = baseTransform;
170+
if (currentEffect && currentEffect.transform) {
171+
currentTransform = currentEffect.transform;
172+
}
173+
156174
/**
157175
* 处理 Effects
158176
*/
@@ -173,38 +191,27 @@ export function changeFigure(sentence: ISentence): IPerform {
173191
if (durationFromArg && typeof durationFromArg === 'number') {
174192
duration = durationFromArg;
175193
}
176-
let animationObj: AnimationFrame[];
194+
177195
if (transformString) {
178196
console.log(transformString);
179197
try {
180-
const frame = JSON.parse(transformString.toString()) as AnimationFrame;
181-
animationObj = generateTransformAnimationObj(key, frame, duration, ease);
182-
// 因为是切换,必须把一开始的 alpha 改为 0
183-
animationObj[0].alpha = 0;
184-
const animationName = (Math.random() * 10).toString(16);
185-
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
186-
WebGAL.animationManager.addAnimation(newAnimation);
187-
duration = getAnimateDuration(animationName);
188-
WebGAL.animationManager.nextEnterAnimationName.set(key, animationName);
198+
const transform = JSON.parse(transformString.toString()) as ITransform;
199+
const enterFrame = {...transform, duration: 0, ease: ''};
200+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
201+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
202+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
189203
} catch (e) {
190204
// 解析都错误了,歇逼吧
191-
applyDefaultTransform();
205+
const enterFrame = {...baseTransform, duration: 0, ease: ''};
206+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
207+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
208+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
192209
}
193210
} else {
194-
applyDefaultTransform();
195-
}
196-
197-
function applyDefaultTransform() {
198-
// 应用默认的
199-
const frame = {};
200-
animationObj = generateTransformAnimationObj(key, frame as AnimationFrame, duration, ease);
201-
// 因为是切换,必须把一开始的 alpha 改为 0
202-
animationObj[0].alpha = 0;
203-
const animationName = (Math.random() * 10).toString(16);
204-
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
205-
WebGAL.animationManager.addAnimation(newAnimation);
206-
duration = getAnimateDuration(animationName);
207-
WebGAL.animationManager.nextEnterAnimationName.set(key, animationName);
211+
const enterFrame = {...baseTransform, duration: 0, ease: ''};
212+
const exitFrame = {...currentTransform, duration: 0, ease: ''};
213+
createDefaultEnterExitAnimation('enter', key, enterFrame, duration, ease);
214+
createDefaultEnterExitAnimation('exit', key, exitFrame, duration, ease);
208215
}
209216
const enterAnim = getSentenceArgByKey(sentence, 'enter');
210217
const exitAnim = getSentenceArgByKey(sentence, 'exit');
@@ -239,18 +246,12 @@ export function changeFigure(sentence: ISentence): IPerform {
239246
/**
240247
* 下面的代码是设置与位置关联的立绘的
241248
*/
242-
const positionMap = {
243-
center: 'fig-center',
244-
left: 'fig-left',
245-
right: 'fig-right',
246-
};
247249
const dispatchMap: Record<string, keyof IStageState> = {
248250
center: 'figName',
249251
left: 'figNameLeft',
250252
right: 'figNameRight',
251253
};
252254

253-
key = positionMap[pos];
254255
setAnimationNames(key, sentence);
255256
if (motion || overrideBounds) {
256257
dispatch(
@@ -272,6 +273,7 @@ export function changeFigure(sentence: ISentence): IPerform {
272273
isHoldOn: false,
273274
stopFunction: () => {
274275
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key);
276+
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key + '-old' + '-off');
275277
},
276278
blockingNext: () => false,
277279
blockingAuto: () => true,

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export const setTransform = (sentence: ISentence): IPerform => {
2121
const animationName = (Math.random() * 10).toString(16);
2222
const animationString = sentence.content;
2323
let animationObj: AnimationFrame[];
24-
const duration = getSentenceArgByKey(sentence, 'duration');
24+
let duration = 500;
25+
const durationFromArg = getSentenceArgByKey(sentence, 'duration');
26+
if (durationFromArg && typeof durationFromArg === 'number') {
27+
duration = durationFromArg;
28+
}
2529
const ease = (getSentenceArgByKey(sentence, 'ease') as string) ?? '';
2630
const writeDefault = (getSentenceArgByKey(sentence, 'writeDefault') as boolean) ?? false;
2731
const target = (getSentenceArgByKey(sentence, 'target')?.toString() ?? '0') as string;
@@ -32,7 +36,7 @@ export const setTransform = (sentence: ISentence): IPerform => {
3236

3337
try {
3438
const frame = JSON.parse(animationString) as AnimationFrame;
35-
animationObj = generateTransformAnimationObj(target, frame, duration, ease);
39+
animationObj = generateTransformAnimationObj(target, frame, duration, ease, 'normal');
3640
console.log('animationObj:', animationObj);
3741
} catch (e) {
3842
// 解析都错误了,歇逼吧

0 commit comments

Comments
 (0)