Skip to content
Merged
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
50 changes: 29 additions & 21 deletions packages/webgal/src/Core/Modules/animationFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,19 @@ export function getAnimationTimeline(
}
const mappedEffects = effect.effects.map((effect) => {
const targetSetEffect = stageStateManager.getCalculationStageState().effects.find((e) => e.target === target);
const sourceTransform =
!writeDefault && targetSetEffect && targetSetEffect.transform ? targetSetEffect.transform : baseTransform;
let newEffect;

if (!writeDefault && targetSetEffect && targetSetEffect.transform) {
if (writeFullEffect) {
newEffect = cloneDeep({ ...targetSetEffect.transform, duration: 0, ease: '' });
} else {
const targetScale = pickBy(targetSetEffect.transform.scale || {}, (source, key) => unionScaleKeys.has(key));
const targetPosition = pickBy(targetSetEffect.transform.position || {}, (s, key) => unionPositionKeys.has(key));
const originalTransform = { ...pickBy(targetSetEffect.transform, (source, key) => unionKeys.has(key)) };
originalTransform.scale = targetScale;
originalTransform.position = targetPosition;
newEffect = cloneDeep({ ...originalTransform, duration: 0, ease: '' });
}
if (writeFullEffect) {
newEffect = cloneDeep({ ...sourceTransform, duration: 0, ease: '' });
} else {
newEffect = cloneDeep({ ...baseTransform, duration: 0, ease: '' });
const targetScale = pickBy(sourceTransform.scale || {}, (source, key) => unionScaleKeys.has(key));
const targetPosition = pickBy(sourceTransform.position || {}, (s, key) => unionPositionKeys.has(key));
const originalTransform = { ...pickBy(sourceTransform, (source, key) => unionKeys.has(key)) };
if (unionScaleKeys.size > 0) originalTransform.scale = targetScale;
if (unionPositionKeys.size > 0) originalTransform.position = targetPosition;
Comment on lines +78 to +80

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When writeFullEffect is false, pickBy is used to copy properties from sourceTransform based on unionKeys. However, since scale and position are nested objects, copying them directly by reference can lead to unexpected behavior if they are not being animated (i.e., when unionScaleKeys or unionPositionKeys are empty).

By explicitly excluding 'scale' and 'position' from the initial pickBy call, we can ensure they are only added to originalTransform when they are actually being animated.

        const originalTransform = {
          ...pickBy(sourceTransform, (source, key) => unionKeys.has(key) && key !== 'scale' && key !== 'position'),
        };
        if (unionScaleKeys.size > 0) originalTransform.scale = targetScale;
        if (unionPositionKeys.size > 0) originalTransform.position = targetPosition;

newEffect = cloneDeep({ ...originalTransform, duration: 0, ease: '' });
}

PixiStage.assignTransform(newEffect, effect, false);
Expand Down Expand Up @@ -121,22 +119,26 @@ export function getEnterExitAnimation(
if (isBg) {
duration = DEFAULT_BG_IN_DURATION;
}
duration =
stageStateManager.getCalculationStageState().animationSettings.find((setting) => setting.target === target)
?.enterDuration ??
duration;
const animationSettings = stageStateManager
.getCalculationStageState()
.animationSettings.find((setting) => setting.target === target);
duration = animationSettings?.enterDuration ?? duration;
// 走默认动画
let animation: IAnimationObject | null = generateUniversalSoftInAnimationObj(realTarget ?? target, duration);

const transformState = stageStateManager.getCalculationStageState().effects;
const targetEffect = transformState.find((effect) => effect.target === target);

const animationName = stageStateManager
.getCalculationStageState()
.animationSettings.find((setting) => setting.target === target)?.enterAnimationName;
const animationName = animationSettings?.enterAnimationName;
if (animationName && !targetEffect) {
logger.debug('取代默认进入动画', target);
animation = getAnimationObject(animationName, realTarget ?? target, getAnimateDuration(animationName), false);
animation = getAnimationObject(
animationName,
realTarget ?? target,
getAnimateDuration(animationName),
false,
!(animationSettings?.enterAnimationIgnoreDefault ?? false),
);
duration = getAnimateDuration(animationName);
}
return { duration, animation };
Expand All @@ -155,7 +157,13 @@ export function getEnterExitAnimation(
const animationName = animationSettings?.exitAnimationName;
if (animationName) {
logger.debug('取代默认退出动画', target);
animation = getAnimationObject(animationName, realTarget ?? target, getAnimateDuration(animationName), false);
animation = getAnimationObject(
animationName,
realTarget ?? target,
getAnimateDuration(animationName),
false,
!(animationSettings?.exitAnimationIgnoreDefault ?? false),
);
duration = getAnimateDuration(animationName);
}
if (animationSettings) {
Expand Down
2 changes: 2 additions & 0 deletions packages/webgal/src/Core/Modules/stage/stageInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export interface IStageAnimationSetting {
exitAnimationName?: string;
enterDuration?: number;
exitDuration?: number;
enterAnimationIgnoreDefault?: boolean;
exitAnimationIgnoreDefault?: boolean;
}

export type StageAnimationSettingUpdatableKey = Exclude<keyof IStageAnimationSetting, 'target'>;
Expand Down
30 changes: 23 additions & 7 deletions packages/webgal/src/Core/gameScripts/changeBg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IPerform } from '@/Core/Modules/perform/performInterface';
// import {getRandomPerformName} from '../../../util/getRandomPerformName';
import styles from '@/Stage/stage.module.scss';
import { webgalStore } from '@/store/store';
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 '@/Core/Modules/stage/stageInterface';
Expand Down Expand Up @@ -32,6 +32,7 @@ export const changeBg = (sentence: ISentence): IPerform => {
duration = enterDuration;
const exitDuration = getNumberArgByKey(sentence, 'exitDuration') ?? DEFAULT_BG_OUT_DURATION;
const ease = getStringArgByKey(sentence, 'ease') ?? '';
const ignoreDefault = getBooleanArgByKey(sentence, 'ignoreDefault') ?? false;

const dispatch = webgalStore.dispatch;
if (unlockName !== '') {
Expand All @@ -58,7 +59,7 @@ export const changeBg = (sentence: ISentence): IPerform => {
if (transformString) {
try {
const frame = JSON.parse(transformString.toString()) as AnimationFrame;
animationObj = generateTransformAnimationObj('bg-main', frame, enterDuration, ease);
animationObj = generateTransformAnimationObj('bg-main', frame, enterDuration, ease, !ignoreDefault);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
Expand All @@ -77,7 +78,7 @@ export const changeBg = (sentence: ISentence): IPerform => {
function applyDefaultTransform() {
// 应用默认的
const frame = {};
animationObj = generateTransformAnimationObj('bg-main', frame as AnimationFrame, duration, ease);
animationObj = generateTransformAnimationObj('bg-main', frame as AnimationFrame, duration, ease, !ignoreDefault);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
Expand All @@ -86,6 +87,11 @@ export const changeBg = (sentence: ISentence): IPerform => {
duration = getAnimateDuration(animationName);
stageStateManager.updateAnimationSettings({ target: 'bg-main', key: 'enterAnimationName', value: animationName });
}
stageStateManager.updateAnimationSettings({
target: 'bg-main',
key: 'enterAnimationIgnoreDefault',
value: ignoreDefault,
});

// 应用动画的优先级更高一点
const enterAnimation = getStringArgByKey(sentence, 'enter');
Expand All @@ -96,6 +102,11 @@ export const changeBg = (sentence: ISentence): IPerform => {
}
if (exitAnimation) {
stageStateManager.updateAnimationSettings({ target: 'bg-main', key: 'exitAnimationName', value: exitAnimation });
stageStateManager.updateAnimationSettings({
target: 'bg-main',
key: 'exitAnimationIgnoreDefault',
value: ignoreDefault,
});
duration = getAnimateDuration(exitAnimation);
}
if (enterDuration >= 0) {
Expand Down Expand Up @@ -126,11 +137,16 @@ export const changeBg = (sentence: ISentence): IPerform => {
if (sentence.content === '' || !isUrlChanged) {
return;
}
const animationName = stageStateManager
const animationSetting = stageStateManager
.getCalculationStageState()
.animationSettings.find((setting) => setting.target === 'bg-main')?.enterAnimationName;
if (animationName) {
applyAnimationEndState(animationName, 'bg-main', false);
.animationSettings.find((setting) => setting.target === 'bg-main');
if (animationSetting?.enterAnimationName) {
applyAnimationEndState(
animationSetting.enterAnimationName,
'bg-main',
false,
!(animationSetting.enterAnimationIgnoreDefault ?? false),
);
}
},
stopFunction: () => {
Expand Down
28 changes: 22 additions & 6 deletions packages/webgal/src/Core/gameScripts/changeFigure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export function changeFigure(sentence: ISentence): IPerform {
const enterDuration = getNumberArgByKey(sentence, 'enterDuration') ?? duration;
duration = enterDuration;
const exitDuration = getNumberArgByKey(sentence, 'exitDuration') ?? DEFAULT_FIG_OUT_DURATION;
const ignoreDefault = getBooleanArgByKey(sentence, 'ignoreDefault') ?? false;

const currentFigureAssociatedAnimation = stageStateManager.getCalculationStageState().figureAssociatedAnimation;
const filteredFigureAssociatedAnimation = currentFigureAssociatedAnimation.filter((item) => item.targetId !== id);
Expand Down Expand Up @@ -164,7 +165,7 @@ export function changeFigure(sentence: ISentence): IPerform {
console.log(transformString);
try {
const frame = JSON.parse(transformString) as AnimationFrame;
animationObj = generateTransformAnimationObj(key, frame, duration, ease);
animationObj = generateTransformAnimationObj(key, frame, duration, ease, !ignoreDefault);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
Expand All @@ -183,7 +184,7 @@ export function changeFigure(sentence: ISentence): IPerform {
function applyDefaultTransform() {
// 应用默认的
const frame = {};
animationObj = generateTransformAnimationObj(key, frame as AnimationFrame, duration, ease);
animationObj = generateTransformAnimationObj(key, frame as AnimationFrame, duration, ease, !ignoreDefault);
// 因为是切换,必须把一开始的 alpha 改为 0
animationObj[0].alpha = 0;
const animationName = (Math.random() * 10).toString(16);
Expand All @@ -192,13 +193,23 @@ export function changeFigure(sentence: ISentence): IPerform {
duration = getAnimateDuration(animationName);
stageStateManager.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: animationName });
}
stageStateManager.updateAnimationSettings({
target: key,
key: 'enterAnimationIgnoreDefault',
value: ignoreDefault,
});

if (enterAnimation) {
stageStateManager.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: enterAnimation });
duration = getAnimateDuration(enterAnimation);
}
if (exitAnimation) {
stageStateManager.updateAnimationSettings({ target: key, key: 'exitAnimationName', value: exitAnimation });
stageStateManager.updateAnimationSettings({
target: key,
key: 'exitAnimationIgnoreDefault',
value: ignoreDefault,
});
duration = getAnimateDuration(exitAnimation);
}
if (enterDuration >= 0) {
Expand Down Expand Up @@ -287,11 +298,16 @@ export function changeFigure(sentence: ISentence): IPerform {
if (content === '' || !isUrlChanged) {
return;
}
const animationName = stageStateManager
const animationSetting = stageStateManager
.getCalculationStageState()
.animationSettings.find((setting) => setting.target === key)?.enterAnimationName;
if (animationName) {
applyAnimationEndState(animationName, key, false);
.animationSettings.find((setting) => setting.target === key);
if (animationSetting?.enterAnimationName) {
applyAnimationEndState(
animationSetting.enterAnimationName,
key,
false,
!(animationSetting.enterAnimationIgnoreDefault ?? false),
);
}
},
stopFunction: () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/webgal/src/Core/gameScripts/setAnimation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ export const setAnimation = (sentence: ISentence): IPerform => {
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const keep = getBooleanArgByKey(sentence, 'keep') ?? false;
const parallel = getBooleanArgByKey(sentence, 'parallel') ?? false;
const writeFullEffect = !parallel && !(getBooleanArgByKey(sentence, 'ignoreDefault') ?? false);

const key = `${target}-${animationName}-${animationDuration}`;
const performInitName = `animation-${target}`;
const performName = parallel ? `${performInitName}#${animationName}` : performInitName;
let keepAnimationStopped = false;

if (!parallel) WebGAL.gameplay.performController.unmountPerform(performInitName, true);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, !parallel);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, writeFullEffect);

const startFunction = () => {
if (keep && keepAnimationStopped) {
Expand Down
3 changes: 2 additions & 1 deletion packages/webgal/src/Core/gameScripts/setTempAnimation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ export const setTempAnimation = (sentence: ISentence): IPerform => {
const writeDefault = getBooleanArgByKey(sentence, 'writeDefault') ?? false;
const keep = getBooleanArgByKey(sentence, 'keep') ?? false;
const parallel = getBooleanArgByKey(sentence, 'parallel') ?? false;
const writeFullEffect = !parallel && !(getBooleanArgByKey(sentence, 'ignoreDefault') ?? false);

const key = `${target}-${animationName}-${animationDuration}`;
const performInitName = `animation-${target}`;
const performName = parallel ? `${performInitName}#${animationName}` : performInitName;
let keepAnimationStopped = false;

if (!parallel) WebGAL.gameplay.performController.unmountPerform(performInitName, true);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, !parallel);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, writeFullEffect);

const startFunction = () => {
if (keep && keepAnimationStopped) {
Expand Down
6 changes: 3 additions & 3 deletions packages/webgal/src/Core/gameScripts/setTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const setTransform = (sentence: ISentence): IPerform => {
const target = getStringArgByKey(sentence, 'target') ?? '0';
const keep = getBooleanArgByKey(sentence, 'keep') ?? false;
const parallel = getBooleanArgByKey(sentence, 'parallel') ?? false;
const writeFullEffect = !parallel && !(getBooleanArgByKey(sentence, 'ignoreDefault') ?? false);

const performInitName = `animation-${target}`;
const performName = parallel ? `${performInitName}#${animationName}` : performInitName;
Expand All @@ -32,8 +33,7 @@ export const setTransform = (sentence: ISentence): IPerform => {

try {
const frame = JSON.parse(animationString) as AnimationFrame;
// 保持 writeDefault 的旧语义;是否写完整字段由 parallel 单独控制
animationObj = generateTransformAnimationObj(target, frame, duration, ease, !parallel);
animationObj = generateTransformAnimationObj(target, frame, duration, ease, writeFullEffect);
console.log('animationObj:', animationObj);
} catch (e) {
// 解析都错误了,歇逼吧
Expand All @@ -43,7 +43,7 @@ export const setTransform = (sentence: ISentence): IPerform => {
const newAnimation: IUserAnimation = { name: animationName, effects: animationObj };
WebGAL.animationManager.addAnimation(newAnimation);
const animationDuration = getAnimateDuration(animationName);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, !parallel);
const animationTimeline = applyAnimationEndState(animationName, target, writeDefault, writeFullEffect);
const key = `${target}-${animationName}-${animationDuration}`;
let keepAnimationStopped = false;
const startFunction = () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/webgal/src/Core/gameScripts/setTransition.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ISentence } from '@/Core/controller/scene/sceneInterface';
import { createNonePerform, IPerform } from '@/Core/Modules/perform/performInterface';
import { getStringArgByKey } from '@/Core/util/getSentenceArg';
import { getBooleanArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';

/**
Expand All @@ -12,11 +12,18 @@ export const setTransition = (sentence: ISentence): IPerform => {
let key = getStringArgByKey(sentence, 'target') ?? '0';
const enterAnimation = getStringArgByKey(sentence, 'enter');
const exitAnimation = getStringArgByKey(sentence, 'exit');
const ignoreDefault = getBooleanArgByKey(sentence, 'ignoreDefault') ?? false;
if (enterAnimation) {
stageStateManager.updateAnimationSettings({ target: key, key: 'enterAnimationName', value: enterAnimation });
stageStateManager.updateAnimationSettings({
target: key,
key: 'enterAnimationIgnoreDefault',
value: ignoreDefault,
});
}
if (exitAnimation) {
stageStateManager.updateAnimationSettings({ target: key, key: 'exitAnimationName', value: exitAnimation });
stageStateManager.updateAnimationSettings({ target: key, key: 'exitAnimationIgnoreDefault', value: ignoreDefault });
}
return createNonePerform({ blockingAuto: false });
};
Loading