@@ -3,10 +3,14 @@ import { logger } from '@/Core/util/logger';
33import { generateUniversalSoftOffAnimationObj } from '@/Core/controller/stage/pixi/animations/universalSoftOff' ;
44import { webgalStore } from '@/store/store' ;
55import cloneDeep from 'lodash/cloneDeep' ;
6- import { baseTransform } from '@/store/stageInterface' ;
6+ import { baseTransform , IEffect , ITransform } from '@/store/stageInterface' ;
77import { generateTimelineObj } from '@/Core/controller/stage/pixi/animations/timeline' ;
88import { WebGAL } from '@/Core/WebGAL' ;
9- import PixiStage , { IAnimationObject } from '@/Core/controller/stage/pixi/PixiController' ;
9+ import PixiStage , { IAnimationObject , IStageObject } from '@/Core/controller/stage/pixi/PixiController' ;
10+ import { AnimationFrame , IUserAnimation } from './animations' ;
11+ import { generateTransformAnimationObj } from '../controller/stage/pixi/animations/generateTransformAnimationObj' ;
12+ import { getNumberArgByKey , getStringArgByKey } from '../util/getSentenceArg' ;
13+ import { ISentence } from '../controller/scene/sceneInterface' ;
1014
1115// eslint-disable-next-line max-params
1216export function getAnimationObject ( animationName : string , target : string , duration : number , writeDefault : boolean ) {
@@ -45,51 +49,210 @@ export function getAnimateDuration(animationName: string) {
4549 return 0 ;
4650}
4751
52+ /***
53+ * 获取入场或退场动画的对象
54+ * @param target 目标对象
55+ * @param type 动画类型,'enter' 或 'exit'
56+ * @param realTarget 真正的目标对象,用于立绘和背景移除时,打上特殊标记
57+ */
4858// eslint-disable-next-line max-params
4959export function getEnterExitAnimation (
5060 target : string ,
5161 type : 'enter' | 'exit' ,
52- isBg = false ,
53- realTarget ?: string , // 用于立绘和背景移除时,以当前时间打上特殊标记
62+ realTarget ?: string ,
5463) : {
5564 duration : number ;
5665 animation : IAnimationObject | null ;
5766} {
67+ let duration = 500 ;
68+ // 走默认动画
69+ let animation : IAnimationObject | null = null ;
70+ let animationName : string | undefined ;
5871 if ( type === 'enter' ) {
59- let duration = 500 ;
60- if ( isBg ) {
61- duration = 1500 ;
62- }
63- // 走默认动画
64- let animation : IAnimationObject | null = generateUniversalSoftInAnimationObj ( realTarget ?? target , duration ) ;
65-
66- const transformState = webgalStore . getState ( ) . stage . effects ;
67- const targetEffect = transformState . find ( ( effect ) => effect . target === target ) ;
68-
69- const animarionName = WebGAL . animationManager . nextEnterAnimationName . get ( target ) ;
70- if ( animarionName && ! targetEffect ) {
71- logger . debug ( '取代默认进入动画' , target ) ;
72- animation = getAnimationObject ( animarionName , realTarget ?? target , getAnimateDuration ( animarionName ) , false ) ;
73- duration = getAnimateDuration ( animarionName ) ;
74- // 用后重置
72+ animation = generateUniversalSoftInAnimationObj ( realTarget ?? target , duration ) ;
73+ animationName = WebGAL . animationManager . nextEnterAnimationName . get ( target ) ;
74+ } else {
75+ animation = generateUniversalSoftOffAnimationObj ( realTarget ?? target , duration ) ;
76+ animationName = WebGAL . animationManager . nextExitAnimationName . get ( target ) ;
77+ }
78+
79+ const transformState = webgalStore . getState ( ) . stage . effects ;
80+ const targetEffect = transformState . find ( ( effect ) => effect . target === target ) ;
81+
82+ if ( animationName && ! targetEffect ) {
83+ logger . debug ( `取代默认 ${ type === 'enter' ? '入场' : '退场' } 动画` , target ) ;
84+ animation = getAnimationObject ( animationName , realTarget ?? target , getAnimateDuration ( animationName ) , false ) ;
85+ duration = getAnimateDuration ( animationName ) ;
86+ // 用后重置
87+ if ( type === 'enter' ) {
7588 WebGAL . animationManager . nextEnterAnimationName . delete ( target ) ;
89+ } else {
90+ WebGAL . animationManager . nextExitAnimationName . delete ( target ) ;
7691 }
77- return { duration, animation } ;
92+ }
93+ return { duration, animation } ;
94+ }
95+
96+ /**
97+ * 创建默认的入场或退场动画
98+ * @param type 动画类型,'enter' 或 'exit'
99+ * @param target 目标对象
100+ * @param frame 应用的动画帧
101+ * @param duration 动画持续时间
102+ * @param ease 缓动类型
103+ */
104+ // eslint-disable-next-line max-params
105+ export function createDefaultEnterExitAnimation (
106+ type : 'enter' | 'exit' ,
107+ target : string ,
108+ frame : AnimationFrame ,
109+ duration : number ,
110+ ease : string ,
111+ ) {
112+ const animationObj = generateTransformAnimationObj ( target , frame , duration , ease , type ) ;
113+ const animationName = ( Math . random ( ) * 10 ) . toString ( 16 ) ;
114+ const newAnimation : IUserAnimation = { name : animationName , effects : animationObj } ;
115+ WebGAL . animationManager . addAnimation ( newAnimation ) ;
116+ if ( type === 'enter' ) {
117+ WebGAL . animationManager . nextEnterAnimationName . set ( target , animationName ) ;
78118 } else {
79- let duration = 1000 ;
80- if ( isBg ) {
81- duration = 1500 ;
119+ WebGAL . animationManager . nextExitAnimationName . set ( target , animationName ) ;
120+ }
121+ }
122+
123+ // eslint-disable-next-line max-params
124+ export function createEnterExitAnimation (
125+ sentence : ISentence ,
126+ targetKey : string ,
127+ defaultDuration : number ,
128+ currentTransform : ITransform ,
129+ ) : number {
130+ // 处理 transform 和 默认 transform
131+ const transformString = getStringArgByKey ( sentence , 'transform' ) ;
132+ const ease = getStringArgByKey ( sentence , 'ease' ) ?? '' ;
133+ let duration = getNumberArgByKey ( sentence , 'duration' ) ?? defaultDuration ;
134+
135+ if ( transformString ) {
136+ console . log ( transformString ) ;
137+ try {
138+ const transform = JSON . parse ( transformString . toString ( ) ) as ITransform ;
139+ const enterFrame = { ...transform , duration : 0 , ease : '' } ;
140+ const exitFrame = { ...currentTransform , duration : 0 , ease : '' } ;
141+ createDefaultEnterExitAnimation ( 'enter' , targetKey , enterFrame , duration , ease ) ;
142+ createDefaultEnterExitAnimation ( 'exit' , targetKey , exitFrame , duration , ease ) ;
143+ } catch ( e ) {
144+ // 解析都错误了,歇逼吧
145+ applyDefaultTransform ( ) ;
82146 }
83- // 走默认动画
84- let animation : IAnimationObject | null = generateUniversalSoftOffAnimationObj ( realTarget ?? target , duration ) ;
85- const animarionName = WebGAL . animationManager . nextExitAnimationName . get ( target ) ;
86- if ( animarionName ) {
87- logger . debug ( '取代默认退出动画' , target ) ;
88- animation = getAnimationObject ( animarionName , realTarget ?? target , getAnimateDuration ( animarionName ) , false ) ;
89- duration = getAnimateDuration ( animarionName ) ;
90- // 用后重置
91- WebGAL . animationManager . nextExitAnimationName . delete ( target ) ;
147+ } else {
148+ applyDefaultTransform ( ) ;
149+ }
150+
151+ function applyDefaultTransform ( ) {
152+ const enterFrame = { ...baseTransform , duration : 0 , ease : '' } ;
153+ const exitFrame = { ...currentTransform , duration : 0 , ease : '' } ;
154+ createDefaultEnterExitAnimation ( 'enter' , targetKey , enterFrame , duration , ease ) ;
155+ createDefaultEnterExitAnimation ( 'exit' , targetKey , exitFrame , duration , ease ) ;
156+ }
157+
158+ const enterAnimation = getStringArgByKey ( sentence , 'enter' ) ;
159+ const exitAnimation = getStringArgByKey ( sentence , 'exit' ) ;
160+ if ( enterAnimation ) {
161+ WebGAL . animationManager . nextEnterAnimationName . set ( targetKey , enterAnimation ) ;
162+ duration = getAnimateDuration ( enterAnimation ) ;
163+ }
164+ if ( exitAnimation ) {
165+ WebGAL . animationManager . nextExitAnimationName . set ( targetKey , exitAnimation ) ;
166+ duration = getAnimateDuration ( exitAnimation ) ;
167+ }
168+
169+ return duration ;
170+ }
171+
172+ export function getOldTargetSuffix ( ) : string {
173+ return '-old' ;
174+ }
175+
176+ export function getOldTargetKey ( targetKey : string ) : string {
177+ return targetKey + getOldTargetSuffix ( ) ;
178+ }
179+
180+ export function getEnterAnimationKey ( targetKey : string ) : string {
181+ return targetKey + '-enter' ;
182+ }
183+
184+ export function getExitAnimationKey ( targetKey : string ) : string {
185+ return targetKey + '-exit' ;
186+ }
187+
188+ /**
189+ * 移除指定的场景对象及其动画
190+ * @param targetKey 目标对象的 key
191+ * @param currentEffects 当前场景效果列表
192+ */
193+ export function removeStageObjectWithAnimationByKey ( targetKey : string , currentEffects : IEffect [ ] ) {
194+ const enterAnimationKey = getEnterAnimationKey ( targetKey ) ;
195+ const exitAnimationKey = getExitAnimationKey ( targetKey ) ;
196+ const oldTargetKey = getOldTargetKey ( targetKey ) ;
197+ // 移除入场动画
198+ WebGAL . gameplay . pixiStage ?. removeAnimation ( enterAnimationKey , true ) ;
199+ // 快进,跳过退出动画
200+ if ( WebGAL . gameplay . isFast ) {
201+ logger . debug ( '快速模式,立刻关闭立绘' ) ;
202+ WebGAL . gameplay . pixiStage ?. removeStageObjectByKey ( targetKey ) ;
203+ return ;
204+ }
205+ // 修改旧目标的 key, 以避免和新目标冲突
206+ const oldTarget = WebGAL . gameplay . pixiStage ?. getStageObjByKey ( targetKey ) ;
207+ if ( oldTarget ) {
208+ oldTarget . key = oldTargetKey ;
209+ // 注册退场动画
210+ const { duration, animation } = getEnterExitAnimation ( targetKey , 'exit' , oldTargetKey ) ;
211+ WebGAL . gameplay . pixiStage ?. registerPresetAnimation ( animation , exitAnimationKey , oldTargetKey , currentEffects ) ;
212+ }
213+ }
214+
215+ /***
216+ * 添加或移除场景对象
217+ * @param targetKey 目标对象的 key
218+ * @param newUrl 新的资源地址
219+ * @param currentEffects 当前场景效果列表
220+ * @param addFunction 添加函数
221+ */
222+ // eslint-disable-next-line max-params
223+ export function addOrRemoveStageObject (
224+ targetKey : string ,
225+ newUrl : string ,
226+ currentEffects : IEffect [ ] ,
227+ addFunction : Function ,
228+ ) {
229+ if ( newUrl !== '' ) {
230+ // 如果对象存在且地址不同,移除旧对象, 并添加新对象
231+ const currentStageObject = WebGAL . gameplay . pixiStage ?. getStageObjByKey ( targetKey ) ;
232+ if ( currentStageObject ) {
233+ if ( currentStageObject . sourceUrl !== newUrl ) {
234+ logger . debug ( `移除目标 ${ targetKey } : ${ currentStageObject . sourceUrl } ` ) ;
235+ removeStageObjectWithAnimationByKey ( targetKey , currentEffects ) ;
236+ // 添加新对象
237+ logger . debug ( `新增目标 ${ targetKey } : ${ newUrl } ` ) ;
238+ addFunction ( ) ;
239+ // 注册入场动画
240+ const enterAnimationKey = getEnterAnimationKey ( targetKey ) ;
241+ const { duration, animation } = getEnterExitAnimation ( targetKey , 'enter' ) ;
242+ WebGAL . gameplay . pixiStage ! . registerPresetAnimation ( animation , enterAnimationKey , targetKey , currentEffects ) ;
243+ }
244+ } else {
245+ // 如果对象不存在,添加新对象
246+ logger . debug ( `新增目标 ${ targetKey } : ${ newUrl } ` ) ;
247+ addFunction ( ) ;
248+ // 注册入场动画
249+ const enterAnimationKey = getEnterAnimationKey ( targetKey ) ;
250+ const { duration, animation } = getEnterExitAnimation ( targetKey , 'enter' ) ;
251+ WebGAL . gameplay . pixiStage ! . registerPresetAnimation ( animation , enterAnimationKey , targetKey , currentEffects ) ;
92252 }
93- return { duration, animation } ;
253+ } else {
254+ // 如果新地址为空,移除对象
255+ logger . debug ( `移除目标 ${ targetKey } ` ) ;
256+ removeStageObjectWithAnimationByKey ( targetKey , currentEffects ) ;
94257 }
95258}
0 commit comments