@@ -166,17 +166,15 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
166166 const animationDeps = useRef ( 0 )
167167 // 记录上次 transition 相关属性,用于判断是否需要重新解析
168168 const lastTransitionStyleRef = useRef < Partial < ExtendedViewStyle > > ( { } )
169- // ** 从 style 中获取动画数据
170- const transitionMap = useMemo ( ( ) => {
171- return parseTransitionStyle ( originalStyle )
172- } , [ ] )
173169 // ** style prop sharedValue interpolateOutput: SharedValue<InterpolateOutput>
174- const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo ( ( ) => {
170+ const { shareValMap, animatedKeys, animatedStyleKeys, transitionMap } = useMemo ( ( ) => {
175171 // 记录需要执行动画的 propName
176172 const animatedKeys = [ ] as string [ ]
177173 // 有动画样式的 style key(useAnimatedStyle使用)
178174 const animatedStyleKeys = [ ] as ( string | string [ ] ) [ ]
179175 const transforms = [ ] as string [ ]
176+ // ** 从 style 中获取动画数据
177+ const transitionMap = parseTransitionStyle ( originalStyle )
180178 const shareValMap = Object . keys ( transitionMap ) . reduce ( ( valMap , property ) => {
181179 // const { property } = transition || {}
182180 if ( property === 'transform' ) {
@@ -201,64 +199,69 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
201199 return {
202200 shareValMap,
203201 animatedKeys,
204- animatedStyleKeys
202+ animatedStyleKeys,
203+ transitionMap
205204 }
206205 } , [ ] )
206+ const transitionMapRef = useRef ( transitionMap )
207207 const runOnJSCallbackRef = useRef ( { } )
208208 const runOnJSCallback = useRunOnJSCallback ( runOnJSCallbackRef )
209209 // 根据 animation action 创建&驱动动画
210- function createAnimation ( key : string , transitionKey : string , timing : { delay ?: number , duration : number , easing : EasingFunction } ) {
210+ function createAnimation ( ) {
211211 let transformTransitionendDone = false
212- const { delay = 0 , duration, easing } = timing
213- const isTransformKey = isTransform ( key )
214- let ruleV = originalStyle [ key ]
215- if ( isTransformKey ) {
216- const transform = getTransformObj ( originalStyle . transform ! )
217- ruleV = transform [ key ]
218- }
219- let toVal = ruleV !== undefined
220- ? ruleV
221- : transitionSupportedProperty [ key ]
222- const shareVal = shareValMap [ key ] . value
223- if ( percentExp . test ( `${ toVal } ` ) && ! percentExp . test ( shareVal as string ) && ! isNaN ( + shareVal ) ) {
224- // 获取到的toVal为百分比格式化shareValMap为百分比
225- shareValMap [ key ] . value = `${ shareVal as number * 100 } %`
226- } else if ( percentExp . test ( shareVal as string ) && ! percentExp . test ( toVal as string ) && ! isNaN ( + toVal ) ) {
227- // 初始值为百分比则格式化toVal为百分比
228- toVal = `${ toVal * 100 } %`
229- } else if ( typeof toVal !== typeof shareVal ) {
230- // 动画起始值和终态值类型不一致报错提示一下
231- warn ( `[Mpx runtime error]: Value types of property ${ key } must be consistent during the animation` )
232- }
233- if ( ( toVal === 'auto' && ! isNaN ( + shareVal ) ) || ( shareVal === 'auto' && ! isNaN ( + toVal ) ) ) {
234- // 有 auto 直接赋值不做动画
235- shareValMap [ key ] . value = toVal
236- } else {
237- // console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
238- // console.log('animationOptions=', { delay, duration, easing })
239- let callback
240- if ( transitionend && ( ! isTransformKey || ! transformTransitionendDone ) ) {
241- runOnJSCallbackRef . current = {
242- animationCallback : ( duration : number , finished : boolean , current ?: AnimatableValue ) => {
243- transitionend ( finished , current , duration )
212+ animatedKeys . forEach ( key => {
213+ // console.log(`createAnimation key=${key} originalStyle=`, originalStyle)
214+ const isTransformKey = isTransform ( key )
215+ let ruleV = originalStyle [ key ]
216+ if ( isTransformKey ) {
217+ const transform = getTransformObj ( originalStyle . transform ! )
218+ ruleV = transform [ key ]
219+ }
220+ let toVal = ruleV !== undefined
221+ ? ruleV
222+ : transitionSupportedProperty [ key ]
223+ const shareVal = shareValMap [ key ] . value
224+ if ( percentExp . test ( `${ toVal } ` ) && ! percentExp . test ( shareVal as string ) && ! isNaN ( + shareVal ) ) {
225+ // 获取到的toVal为百分比格式化shareValMap为百分比
226+ shareValMap [ key ] . value = `${ shareVal as number * 100 } %`
227+ } else if ( percentExp . test ( shareVal as string ) && ! percentExp . test ( toVal as string ) && ! isNaN ( + toVal ) ) {
228+ // 初始值为百分比则格式化toVal为百分比
229+ toVal = `${ toVal * 100 } %`
230+ } else if ( typeof toVal !== typeof shareVal ) {
231+ // 动画起始值和终态值类型不一致报错提示一下
232+ warn ( `[Mpx runtime error]: Value types of property ${ key } must be consistent during the animation` )
233+ }
234+ if ( ( toVal === 'auto' && ! isNaN ( + shareVal ) ) || ( shareVal === 'auto' && ! isNaN ( + toVal ) ) ) {
235+ // 有 auto 直接赋值不做动画
236+ shareValMap [ key ] . value = toVal
237+ } else {
238+ // console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
239+ const { delay = 0 , duration = 0 , easing = Easing . inOut ( Easing . ease ) } = transitionMapRef . current [ isTransformKey ? 'transform' : key ] || { }
240+ // console.log('animationOptions=', { delay, duration, easing })
241+ let callback
242+ if ( transitionend && ( ! isTransformKey || ! transformTransitionendDone ) ) {
243+ runOnJSCallbackRef . current = {
244+ animationCallback : ( duration : number , finished : boolean , current ?: AnimatableValue ) => {
245+ transitionend ( finished , current , duration )
246+ }
244247 }
245- }
246- callback = ( finished ?: boolean , current ?: AnimatableValue ) => {
247- 'worklet'
248- // 动画结束后设置下一次transformOrigin
249- if ( finished ) {
250- runOnJS ( runOnJSCallback ) ( 'animationCallback' , duration , finished , current )
248+ callback = ( finished ?: boolean , current ?: AnimatableValue ) => {
249+ 'worklet'
250+ // 动画结束后设置下一次transformOrigin
251+ if ( finished ) {
252+ runOnJS ( runOnJSCallback ) ( 'animationCallback' , duration , finished , current )
253+ }
251254 }
252255 }
256+ const animation = getAnimation ( { key, value : toVal ! } , { delay, duration, easing } , callback )
257+ // Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
258+ if ( isTransformKey ) {
259+ transformTransitionendDone = true
260+ }
261+ shareValMap [ key ] . value = animation
253262 }
254- const animation = getAnimation ( { key, value : toVal ! } , { delay, duration, easing } , callback )
255- // Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
256- if ( isTransformKey ) {
257- transformTransitionendDone = true
258- }
259- shareValMap [ key ] . value = animation
260- }
261- // console.log(`useTransitionHooks, ${key}=`, animation)
263+ // console.log(`useTransitionHooks, ${key}=`, animation)
264+ } )
262265 }
263266 // ** style 更新
264267 useEffect ( ( ) => {
@@ -271,25 +274,21 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
271274 // 仅当 transition 相关属性变化时才重新解析
272275 const prevStyle = lastTransitionStyleRef . current
273276 const hasTransitionChanged = transitionKeys . some ( key => prevStyle [ key ] !== originalStyle [ key ] )
274- if ( ! hasTransitionChanged ) {
275- return
276- }
277- lastTransitionStyleRef . current = {
278- transition : originalStyle . transition ,
279- transitionDuration : originalStyle . transitionDuration ,
280- transitionProperty : originalStyle . transitionProperty ,
281- transitionTimingFunction : originalStyle . transitionTimingFunction ,
282- transitionDelay : originalStyle . transitionDelay
277+ const currentTransitionMap = hasTransitionChanged
278+ ? parseTransitionStyle ( originalStyle )
279+ : transitionMapRef . current
280+ if ( hasTransitionChanged ) {
281+ lastTransitionStyleRef . current = {
282+ transition : originalStyle . transition ,
283+ transitionDuration : originalStyle . transitionDuration ,
284+ transitionProperty : originalStyle . transitionProperty ,
285+ transitionTimingFunction : originalStyle . transitionTimingFunction ,
286+ transitionDelay : originalStyle . transitionDelay
287+ }
288+ transitionMapRef . current = currentTransitionMap
283289 }
284290 // 从当前 style 解析最新 timing
285- const currentTransitionMap = parseTransitionStyle ( originalStyle )
286- animatedKeys . forEach ( key => {
287- const transitionKey = isTransform ( key ) ? 'transform' : key
288- const timing = currentTransitionMap [ transitionKey ] // || transitionMap[transitionKey]
289- if ( timing ) {
290- createAnimation ( key , transitionKey , timing )
291- }
292- } )
291+ createAnimation ( )
293292 } , [ originalStyle ] )
294293 // ** 清空动画
295294 useEffect ( ( ) => {
0 commit comments