diff --git a/packages/webgal/src/Core/Modules/animationFunctions.ts b/packages/webgal/src/Core/Modules/animationFunctions.ts index 7cbc5ea37..1ba79e854 100644 --- a/packages/webgal/src/Core/Modules/animationFunctions.ts +++ b/packages/webgal/src/Core/Modules/animationFunctions.ts @@ -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; + newEffect = cloneDeep({ ...originalTransform, duration: 0, ease: '' }); } PixiStage.assignTransform(newEffect, effect, false); @@ -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 }; @@ -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) { diff --git a/packages/webgal/src/Core/Modules/stage/stageInterface.ts b/packages/webgal/src/Core/Modules/stage/stageInterface.ts index d5ae57247..4e8cd25f5 100644 --- a/packages/webgal/src/Core/Modules/stage/stageInterface.ts +++ b/packages/webgal/src/Core/Modules/stage/stageInterface.ts @@ -83,6 +83,8 @@ export interface IStageAnimationSetting { exitAnimationName?: string; enterDuration?: number; exitDuration?: number; + enterAnimationIgnoreDefault?: boolean; + exitAnimationIgnoreDefault?: boolean; } export type StageAnimationSettingUpdatableKey = Exclude; diff --git a/packages/webgal/src/Core/gameScripts/changeBg/index.ts b/packages/webgal/src/Core/gameScripts/changeBg/index.ts index ad30b3c57..f65d6d350 100644 --- a/packages/webgal/src/Core/gameScripts/changeBg/index.ts +++ b/packages/webgal/src/Core/gameScripts/changeBg/index.ts @@ -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'; @@ -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 !== '') { @@ -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); @@ -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); @@ -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'); @@ -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) { @@ -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: () => { diff --git a/packages/webgal/src/Core/gameScripts/changeFigure.ts b/packages/webgal/src/Core/gameScripts/changeFigure.ts index 91fb96f5f..b6b64e6e4 100644 --- a/packages/webgal/src/Core/gameScripts/changeFigure.ts +++ b/packages/webgal/src/Core/gameScripts/changeFigure.ts @@ -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); @@ -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); @@ -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); @@ -192,6 +193,11 @@ 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 }); @@ -199,6 +205,11 @@ export function changeFigure(sentence: ISentence): IPerform { } if (exitAnimation) { stageStateManager.updateAnimationSettings({ target: key, key: 'exitAnimationName', value: exitAnimation }); + stageStateManager.updateAnimationSettings({ + target: key, + key: 'exitAnimationIgnoreDefault', + value: ignoreDefault, + }); duration = getAnimateDuration(exitAnimation); } if (enterDuration >= 0) { @@ -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: () => { diff --git a/packages/webgal/src/Core/gameScripts/setAnimation.ts b/packages/webgal/src/Core/gameScripts/setAnimation.ts index b9c563661..24af0fefa 100644 --- a/packages/webgal/src/Core/gameScripts/setAnimation.ts +++ b/packages/webgal/src/Core/gameScripts/setAnimation.ts @@ -20,6 +20,7 @@ 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}`; @@ -27,7 +28,7 @@ export const setAnimation = (sentence: ISentence): IPerform => { 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) { diff --git a/packages/webgal/src/Core/gameScripts/setTempAnimation.ts b/packages/webgal/src/Core/gameScripts/setTempAnimation.ts index d7c31c273..dc06c9f96 100644 --- a/packages/webgal/src/Core/gameScripts/setTempAnimation.ts +++ b/packages/webgal/src/Core/gameScripts/setTempAnimation.ts @@ -29,6 +29,7 @@ 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}`; @@ -36,7 +37,7 @@ export const setTempAnimation = (sentence: ISentence): IPerform => { 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) { diff --git a/packages/webgal/src/Core/gameScripts/setTransform.ts b/packages/webgal/src/Core/gameScripts/setTransform.ts index ef6bc8f30..f306c34ea 100644 --- a/packages/webgal/src/Core/gameScripts/setTransform.ts +++ b/packages/webgal/src/Core/gameScripts/setTransform.ts @@ -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; @@ -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) { // 解析都错误了,歇逼吧 @@ -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 = () => { diff --git a/packages/webgal/src/Core/gameScripts/setTransition.ts b/packages/webgal/src/Core/gameScripts/setTransition.ts index 1f9f82685..3b1232564 100644 --- a/packages/webgal/src/Core/gameScripts/setTransition.ts +++ b/packages/webgal/src/Core/gameScripts/setTransition.ts @@ -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'; /** @@ -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 }); };