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
32 changes: 32 additions & 0 deletions packages/webgal/src/Core/Modules/animationFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,35 @@ export function getEnterExitAnimation(
return { duration, animation };
}
}

// eslint-disable-next-line max-params
export function registerTimelineAnimation(
animationName: string,
animationKey: string,
target: string,
animationDuration: number,
writeDefault: boolean,
) {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(target);
const animationObj: IAnimationObject | null = getAnimationObject(
animationName,
target,
animationDuration,
writeDefault,
);
if (animationObj) {
logger.debug(`动画${animationName}作用在${target}`, animationDuration);
WebGAL.gameplay.pixiStage?.registerAnimation(animationObj, animationKey, target);
}
}

export function removeTimelineAnimation(animationKey: string, keep: boolean): boolean {
if (keep) {
WebGAL.gameplay.pixiStage?.removeAnimationWithoutSetEndState(animationKey);
return true;
}
setTimeout(() => {
WebGAL.gameplay.pixiStage?.removeAnimationWithSetEffects(animationKey);
}, 0);
return false;
}
52 changes: 37 additions & 15 deletions packages/webgal/src/Core/gameScripts/changeBg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import { IPerform } from '@/Core/Modules/perform/performInterface';
import styles from '@/Stage/stage.module.scss';
import { webgalStore } from '@/store/store';
import { setStage, stageActions } from '@/store/stageReducer';
import { getNumberArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { getBooleanArgByKey, getNumberArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { unlockCgInUserData } from '@/store/userDataReducer';
import { logger } from '@/Core/util/logger';
import { ITransform } from '@/store/stageInterface';
import { generateTransformAnimationObj } from '@/Core/controller/stage/pixi/animations/generateTransformAnimationObj';
import { AnimationFrame, IUserAnimation } from '@/Core/Modules/animations';
import cloneDeep from 'lodash/cloneDeep';
import { getAnimateDuration } from '@/Core/Modules/animationFunctions';
import {
getAnimateDuration,
registerTimelineAnimation,
removeTimelineAnimation,
} from '@/Core/Modules/animationFunctions';
import { WebGAL } from '@/Core/WebGAL';
import { DEFAULT_BG_OUT_DURATION } from '@/Core/constants';
import localforage from 'localforage';
Expand All @@ -27,6 +31,7 @@ export const changeBg = (sentence: ISentence): IPerform => {
const series = getStringArgByKey(sentence, 'series') ?? 'default';
const transformString = getStringArgByKey(sentence, 'transform');
let duration = getNumberArgByKey(sentence, 'duration') ?? DEFAULT_BG_OUT_DURATION;
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const enterDuration = getNumberArgByKey(sentence, 'enterDuration') ?? duration;
duration = enterDuration;
const exitDuration = getNumberArgByKey(sentence, 'exitDuration') ?? DEFAULT_BG_OUT_DURATION;
Expand All @@ -52,21 +57,29 @@ export const changeBg = (sentence: ISentence): IPerform => {
dispatch(stageActions.removeAnimationSettingsByTarget(`bg-main`));
}

const animationName = (Math.random() * 10).toString(16);
const animationKey = `bg-main-${animationName}`;

// 处理 transform 和 默认 transform
let animationObj: AnimationFrame[];
if (transformString) {
try {
const frame = JSON.parse(transformString.toString()) as AnimationFrame;
animationObj = generateTransformAnimationObj('bg-main', frame, enterDuration, ease);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
WebGAL.animationManager.addAnimation(newAnimation);
duration = getAnimateDuration(animationName);
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
);
if (isUrlChanged) {
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
);
} else {
const animationPerformInitName = `animation-bg-main`;
WebGAL.gameplay.performController.unmountPerform(animationPerformInitName, true);
setTimeout(() => {
registerTimelineAnimation(animationName, animationKey, 'bg-main', duration, writeDefault);
}, 0);
}
} catch (e) {
// 解析都错误了,歇逼吧
applyDefaultTransform();
Expand All @@ -79,15 +92,20 @@ export const changeBg = (sentence: ISentence): IPerform => {
// 应用默认的
const frame = {};
animationObj = generateTransformAnimationObj('bg-main', frame as AnimationFrame, duration, ease);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
WebGAL.animationManager.addAnimation(newAnimation);
duration = getAnimateDuration(animationName);
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
);
if (isUrlChanged) {
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName }),
);
} else if (transformString) {
const animationPerformInitName = `animation-bg-main`;
WebGAL.gameplay.performController.unmountPerform(animationPerformInitName, true);
setTimeout(() => {
registerTimelineAnimation(animationName, animationKey, 'bg-main', duration, writeDefault);
}, 0);
}
}

// 应用动画的优先级更高一点
Expand Down Expand Up @@ -134,7 +152,11 @@ export const changeBg = (sentence: ISentence): IPerform => {
duration,
isHoldOn: false,
stopFunction: () => {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget('bg-main');
if (isUrlChanged) {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget('bg-main');
} else {
removeTimelineAnimation(animationKey, false);
}
},
blockingNext: () => false,
blockingAuto: () => true,
Expand Down
51 changes: 37 additions & 14 deletions packages/webgal/src/Core/gameScripts/changeFigure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { AnimationFrame, IUserAnimation } from '@/Core/Modules/animations';
import { generateTransformAnimationObj } from '@/Core/controller/stage/pixi/animations/generateTransformAnimationObj';
import { assetSetter, fileType } from '@/Core/util/gameAssetsAccess/assetSetter';
import { logger } from '@/Core/util/logger';
import { getAnimateDuration } from '@/Core/Modules/animationFunctions';
import {
getAnimateDuration,
registerTimelineAnimation,
removeTimelineAnimation,
} from '@/Core/Modules/animationFunctions';
import { WebGAL } from '@/Core/WebGAL';
import { baseBlinkParam, baseFocusParam, BlinkParam, FocusParam } from '@/Core/live2DCore';
import { DEFAULT_FIG_IN_DURATION, DEFAULT_FIG_OUT_DURATION, WEBGAL_NONE } from '../constants';
Expand Down Expand Up @@ -88,6 +92,7 @@ export function changeFigure(sentence: ISentence): IPerform {
const transformString = getStringArgByKey(sentence, 'transform');
const ease = getStringArgByKey(sentence, 'ease') ?? '';
let duration = getNumberArgByKey(sentence, 'duration') ?? DEFAULT_FIG_IN_DURATION;
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const enterAnimation = getStringArgByKey(sentence, 'enter');
const exitAnimation = getStringArgByKey(sentence, 'exit');
let zIndex = getNumberArgByKey(sentence, 'zIndex') ?? -1;
Expand Down Expand Up @@ -155,6 +160,10 @@ export function changeFigure(sentence: ISentence): IPerform {
oldStageObject.isExiting = true;
}
}

const animationName = (Math.random() * 10).toString(16);
const animationKey = `${id}-${animationName}`;

const setAnimationNames = (key: string, sentence: ISentence) => {
// 如果立绘被关闭了,那么就不用设置了
if (content === '') {
Expand All @@ -167,15 +176,20 @@ export function changeFigure(sentence: ISentence): IPerform {
try {
const frame = JSON.parse(transformString) as AnimationFrame;
animationObj = generateTransformAnimationObj(key, frame, duration, ease);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
WebGAL.animationManager.addAnimation(newAnimation);
duration = getAnimateDuration(animationName);
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
);
if (isUrlChanged) {
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
);
} else {
const animationPerformInitName = `animation-${id}`;
WebGAL.gameplay.performController.unmountPerform(animationPerformInitName, true);
setTimeout(() => {
registerTimelineAnimation(animationName, animationKey, id, duration, writeDefault);
}, 0);
}
} catch (e) {
// 解析都错误了,歇逼吧
applyDefaultTransform();
Expand All @@ -188,15 +202,20 @@ export function changeFigure(sentence: ISentence): IPerform {
// 应用默认的
const frame = {};
animationObj = generateTransformAnimationObj(key, frame as AnimationFrame, duration, ease);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
WebGAL.animationManager.addAnimation(newAnimation);
duration = getAnimateDuration(animationName);
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
);
if (isUrlChanged) {
webgalStore.dispatch(
stageActions.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName }),
);
} else if (transformString) {
const animationPerformInitName = `animation-${id}`;
WebGAL.gameplay.performController.unmountPerform(animationPerformInitName, true);
setTimeout(() => {
registerTimelineAnimation(animationName, animationKey, id, duration, writeDefault);
}, 0);
}
}

if (enterAnimation) {
Expand Down Expand Up @@ -298,7 +317,11 @@ export function changeFigure(sentence: ISentence): IPerform {
duration,
isHoldOn: false,
stopFunction: () => {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key);
if (isUrlChanged) {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(key);
} else {
removeTimelineAnimation(animationKey, false);
}
},
blockingNext: () => false,
blockingAuto: () => true,
Expand Down
36 changes: 14 additions & 22 deletions packages/webgal/src/Core/gameScripts/setAnimation.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,43 @@
import { ISentence } from '@/Core/controller/scene/sceneInterface';
import { IPerform } from '@/Core/Modules/perform/performInterface';
import { getBooleanArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { IAnimationObject } from '@/Core/controller/stage/pixi/PixiController';
import { logger } from '@/Core/util/logger';
import { webgalStore } from '@/store/store';

import { getAnimateDuration, getAnimationObject } from '@/Core/Modules/animationFunctions';
import {
getAnimateDuration,
registerTimelineAnimation,
removeTimelineAnimation,
} from '@/Core/Modules/animationFunctions';
import { WebGAL } from '@/Core/WebGAL';

/**
* 设置背景动画
* @param sentence
*/
export const setAnimation = (sentence: ISentence): IPerform => {
const startDialogKey = webgalStore.getState().stage.currentDialogKey;
const animationName = sentence.content;
const animationDuration = getAnimateDuration(animationName);
let target = getStringArgByKey(sentence, 'target') ?? '';
target = target !== '' ? target : 'default_id';
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const keep = getBooleanArgByKey(sentence, 'keep') ?? false;

const key = `${target}-${animationName}-${animationDuration}`;
const performInitName = `animation-${target}`;

WebGAL.gameplay.performController.unmountPerform(performInitName, true);

let stopFunction;
const animationKey = `${target}-${animationName}-${animationDuration}`;
let keepAnimationStopped = false;

setTimeout(() => {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(target);
const animationObj: IAnimationObject | null = getAnimationObject(
animationName,
target,
animationDuration,
writeDefault,
);
if (animationObj) {
logger.debug(`动画${animationName}作用在${target}`, animationDuration);
WebGAL.gameplay.pixiStage?.registerAnimation(animationObj, key, target);
if (keep && keepAnimationStopped) {
return;
}
registerTimelineAnimation(animationName, animationKey, target, animationDuration, writeDefault);
}, 0);
stopFunction = () => {
setTimeout(() => {
const endDialogKey = webgalStore.getState().stage.currentDialogKey;
const isHasNext = startDialogKey !== endDialogKey;
WebGAL.gameplay.pixiStage?.removeAnimationWithSetEffects(key);
}, 0);

const stopFunction = () => {
keepAnimationStopped = removeTimelineAnimation(animationKey, keep);
};

return {
Expand Down
36 changes: 14 additions & 22 deletions packages/webgal/src/Core/gameScripts/setTempAnimation.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { ISentence } from '@/Core/controller/scene/sceneInterface';
import { IPerform } from '@/Core/Modules/perform/performInterface';
import { getBooleanArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { IAnimationObject } from '@/Core/controller/stage/pixi/PixiController';
import { logger } from '@/Core/util/logger';
import { webgalStore } from '@/store/store';
import { generateTimelineObj } from '@/Core/controller/stage/pixi/animations/timeline';
import cloneDeep from 'lodash/cloneDeep';
import { baseTransform } from '@/store/stageInterface';
import { IUserAnimation } from '../Modules/animations';
import { getAnimateDuration, getAnimationObject } from '@/Core/Modules/animationFunctions';
import {
getAnimateDuration,
registerTimelineAnimation,
removeTimelineAnimation,
} from '@/Core/Modules/animationFunctions';
import { WebGAL } from '@/Core/WebGAL';

/**
* 设置临时动画
* @param sentence
*/
export const setTempAnimation = (sentence: ISentence): IPerform => {
const startDialogKey = webgalStore.getState().stage.currentDialogKey;
const animationName = (Math.random() * 10).toString(16);
const animationString = sentence.content;
let animationObj;
Expand All @@ -32,31 +34,21 @@ export const setTempAnimation = (sentence: ISentence): IPerform => {
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const keep = getBooleanArgByKey(sentence, 'keep') ?? false;

const key = `${target}-${animationName}-${animationDuration}`;
const performInitName = `animation-${target}`;

WebGAL.gameplay.performController.unmountPerform(performInitName, true);

let stopFunction = () => {};
const animationKey = `${target}-${animationName}-${animationDuration}`;
let keepAnimationStopped = false;

setTimeout(() => {
WebGAL.gameplay.pixiStage?.stopPresetAnimationOnTarget(target);
const animationObj: IAnimationObject | null = getAnimationObject(
animationName,
target,
animationDuration,
writeDefault,
);
if (animationObj) {
logger.debug(`动画${animationName}作用在${target}`, animationDuration);
WebGAL.gameplay.pixiStage?.registerAnimation(animationObj, key, target);
if (keep && keepAnimationStopped) {
return;
}
registerTimelineAnimation(animationName, animationKey, target, animationDuration, writeDefault);
}, 0);
stopFunction = () => {
setTimeout(() => {
const endDialogKey = webgalStore.getState().stage.currentDialogKey;
const isHasNext = startDialogKey !== endDialogKey;
WebGAL.gameplay.pixiStage?.removeAnimationWithSetEffects(key);
}, 0);

const stopFunction = () => {
keepAnimationStopped = removeTimelineAnimation(animationKey, keep);
};

return {
Expand Down
Loading