@mpxjs/webpack-plugin 2.9.64 → 2.9.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/lib/config.js +38 -10
  2. package/lib/index.js +5 -1
  3. package/lib/platform/style/wx/index.js +66 -60
  4. package/lib/platform/template/wx/index.js +12 -8
  5. package/lib/react/processTemplate.js +4 -2
  6. package/lib/react/style-helper.js +2 -5
  7. package/lib/runtime/components/react/context.ts +8 -0
  8. package/lib/runtime/components/react/dist/context.js +1 -0
  9. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -1
  10. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
  11. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +3 -2
  12. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -1
  13. package/lib/runtime/components/react/dist/mpx-icon.jsx +3 -2
  14. package/lib/runtime/components/react/dist/mpx-image/index.jsx +2 -1
  15. package/lib/runtime/components/react/dist/mpx-input.jsx +2 -1
  16. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -1
  17. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -2
  18. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -1
  19. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
  20. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -1
  21. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -1
  22. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +2 -1
  23. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +2 -1
  24. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +4 -2
  25. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -2
  26. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +2 -1
  27. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -1
  28. package/lib/runtime/components/react/dist/mpx-radio.jsx +3 -2
  29. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -3
  30. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +78 -77
  31. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +2 -1
  32. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -2
  33. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -2
  34. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -1
  35. package/lib/runtime/components/react/dist/mpx-view.jsx +45 -15
  36. package/lib/runtime/components/react/dist/mpx-web-view.jsx +4 -3
  37. package/lib/runtime/components/react/dist/useAnimationHooks.js +215 -0
  38. package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
  39. package/lib/runtime/components/react/dist/utils.jsx +50 -37
  40. package/lib/runtime/components/react/mpx-button.tsx +3 -1
  41. package/lib/runtime/components/react/mpx-checkbox-group.tsx +3 -1
  42. package/lib/runtime/components/react/mpx-checkbox.tsx +4 -1
  43. package/lib/runtime/components/react/mpx-form.tsx +2 -1
  44. package/lib/runtime/components/react/mpx-icon.tsx +3 -2
  45. package/lib/runtime/components/react/mpx-image/index.tsx +2 -1
  46. package/lib/runtime/components/react/mpx-input.tsx +2 -1
  47. package/lib/runtime/components/react/mpx-label.tsx +2 -1
  48. package/lib/runtime/components/react/mpx-movable-area.tsx +3 -2
  49. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -1
  50. package/lib/runtime/components/react/mpx-picker/date.tsx +2 -1
  51. package/lib/runtime/components/react/mpx-picker/index.tsx +2 -1
  52. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +2 -1
  53. package/lib/runtime/components/react/mpx-picker/region.tsx +2 -1
  54. package/lib/runtime/components/react/mpx-picker/selector.tsx +2 -1
  55. package/lib/runtime/components/react/mpx-picker/time.tsx +4 -2
  56. package/lib/runtime/components/react/mpx-picker-view-column.tsx +3 -2
  57. package/lib/runtime/components/react/mpx-picker-view.tsx +2 -1
  58. package/lib/runtime/components/react/mpx-radio-group.tsx +2 -1
  59. package/lib/runtime/components/react/mpx-radio.tsx +3 -2
  60. package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -2
  61. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -75
  62. package/lib/runtime/components/react/mpx-swiper/index.tsx +4 -1
  63. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -1
  64. package/lib/runtime/components/react/mpx-switch.tsx +2 -1
  65. package/lib/runtime/components/react/mpx-text.tsx +2 -1
  66. package/lib/runtime/components/react/mpx-view.tsx +55 -23
  67. package/lib/runtime/components/react/mpx-web-view.tsx +4 -3
  68. package/lib/runtime/components/react/types/common.ts +8 -2
  69. package/lib/runtime/components/react/types/global.d.ts +11 -1
  70. package/lib/runtime/components/react/useAnimationHooks.ts +248 -0
  71. package/lib/runtime/components/react/useNodesRef.ts +1 -6
  72. package/lib/runtime/components/react/utils.tsx +71 -50
  73. package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
  74. package/lib/style-compiler/index.js +5 -4
  75. package/lib/template-compiler/compiler.js +127 -158
  76. package/lib/utils/const.js +2 -1
  77. package/lib/web/processStyles.js +6 -2
  78. package/lib/web/processTemplate.js +2 -3
  79. package/lib/wxml/loader.js +1 -1
  80. package/package.json +6 -4
@@ -7,6 +7,9 @@
7
7
  import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent, Text } from 'react-native'
8
8
  import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, Children, cloneElement } from 'react'
9
9
  import useInnerProps from './getInnerListeners'
10
+ import Animated from 'react-native-reanimated'
11
+ import useAnimationHooks from './useAnimationHooks'
12
+ import type { AnimationProp } from './useAnimationHooks'
10
13
  import { ExtendedViewStyle } from './types/common'
11
14
  import useNodesRef, { HandlerRef } from './useNodesRef'
12
15
  import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils'
@@ -14,6 +17,7 @@ import LinearGradient from 'react-native-linear-gradient'
14
17
 
15
18
  export interface _ViewProps extends ViewProps {
16
19
  style?: ExtendedViewStyle
20
+ animation?: AnimationProp
17
21
  children?: ReactNode | ReactNode[]
18
22
  'hover-style'?: ExtendedViewStyle
19
23
  'hover-start-time'?: number
@@ -24,6 +28,7 @@ export interface _ViewProps extends ViewProps {
24
28
  'parent-font-size'?: number
25
29
  'parent-width'?: number
26
30
  'parent-height'?: number
31
+ 'enable-animation'?: boolean
27
32
  bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
28
33
  bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
29
34
  bindtouchend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void
@@ -114,6 +119,17 @@ const applyHandlers = (handlers: Handler[], args: any[]) => {
114
119
  }
115
120
  }
116
121
 
122
+ const normalizeStyle = (style: ExtendedViewStyle = {}) => {
123
+ ['backgroundSize', 'backgroundPosition'].forEach(name => {
124
+ if (style[name] && typeof style[name] === 'string') {
125
+ if (style[name].trim()) {
126
+ style[name] = style[name].split(' ')
127
+ }
128
+ }
129
+ })
130
+ return style
131
+ }
132
+
117
133
  const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && PERCENT_REGEX.test(val)
118
134
 
119
135
  const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val)
@@ -501,7 +517,7 @@ function normalizeBackgroundSize (backgroundSize: Exclude<ExtendedViewStyle['bac
501
517
  }
502
518
 
503
519
  function preParseImage (imageStyle?: ExtendedViewStyle) {
504
- const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = imageStyle || {}
520
+ const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = normalizeStyle(imageStyle) || {}
505
521
  const { type, src, linearInfo } = parseBgImage(backgroundImage)
506
522
 
507
523
  return {
@@ -589,8 +605,8 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
589
605
  }
590
606
  setImageSizeWidth(sizeInfo.current.width)
591
607
  setImageSizeHeight(sizeInfo.current.height)
592
- setShow(true)
593
608
  }
609
+ setShow(true)
594
610
  } else if (sizeInfo.current) {
595
611
  setLayoutInfoWidth(width)
596
612
  setLayoutInfoHeight(height)
@@ -600,7 +616,7 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
600
616
  }
601
617
  }
602
618
 
603
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden' }}>
619
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
604
620
  {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
605
621
  {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
606
622
  </View>
@@ -639,9 +655,11 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
639
655
  'enable-var': enableVar,
640
656
  'external-var-context': externalVarContext,
641
657
  'enable-background': enableBackground,
658
+ 'enable-animation': enableAnimation,
642
659
  'parent-font-size': parentFontSize,
643
660
  'parent-width': parentWidth,
644
- 'parent-height': parentHeight
661
+ 'parent-height': parentHeight,
662
+ animation
645
663
  } = props
646
664
 
647
665
  const [isHover, setIsHover] = useState(false)
@@ -686,7 +704,8 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
686
704
  throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.')
687
705
  }
688
706
 
689
- const { nodeRef } = useNodesRef<View, _ViewProps>(props, ref, {
707
+ const nodeRef = useRef(null)
708
+ useNodesRef<View, _ViewProps>(props, ref, nodeRef, {
690
709
  defaultStyle
691
710
  })
692
711
 
@@ -735,9 +754,10 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
735
754
  layoutProps
736
755
  } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
737
756
 
757
+ const viewStyle = Object.assign({}, innerStyle, layoutStyle)
738
758
  const innerProps = useInnerProps(props, {
739
759
  ref: nodeRef,
740
- style: { ...innerStyle, ...layoutStyle },
760
+ style: viewStyle,
741
761
  ...layoutProps,
742
762
  ...(hoverStyle && {
743
763
  bindtouchstart: onTouchStart,
@@ -752,25 +772,37 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
752
772
  layoutRef
753
773
  })
754
774
 
755
- return (
756
- <View
775
+ enableAnimation = enableAnimation || !!animation
776
+ const enableAnimationRef = useRef(enableAnimation)
777
+ if (enableAnimationRef.current !== enableAnimation) {
778
+ throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
779
+ }
780
+ const finalStyle = enableAnimation
781
+ ? useAnimationHooks({
782
+ animation,
783
+ style: viewStyle
784
+ })
785
+ : viewStyle
786
+ const childNode = wrapWithChildren(props, {
787
+ hasVarDec,
788
+ enableBackground: enableBackgroundRef.current,
789
+ textStyle,
790
+ backgroundStyle,
791
+ varContext: varContextRef.current,
792
+ textProps
793
+ })
794
+ return animation?.actions?.length
795
+ ? (<Animated.View
757
796
  {...innerProps}
797
+ style={finalStyle}
758
798
  >
759
- {
760
- wrapWithChildren(
761
- props,
762
- {
763
- hasVarDec,
764
- enableBackground: enableBackgroundRef.current,
765
- textStyle,
766
- backgroundStyle,
767
- varContext: varContextRef.current,
768
- textProps
769
- }
770
- )
771
- }
772
- </View>
773
- )
799
+ {childNode}
800
+ </Animated.View>)
801
+ : (<View
802
+ {...innerProps}
803
+ >
804
+ {childNode}
805
+ </View>)
774
806
  })
775
807
 
776
808
  _View.displayName = 'mpx-view'
@@ -1,4 +1,4 @@
1
- import { forwardRef, JSX, useEffect } from 'react'
1
+ import { forwardRef, JSX, useEffect, useRef } from 'react'
2
2
  import { noop, warn } from '@mpxjs/utils'
3
3
  import { Portal } from '@ant-design/react-native'
4
4
  import { getCustomEvent } from './getInnerListeners'
@@ -47,7 +47,7 @@ interface FormRef {
47
47
  }
48
48
 
49
49
  const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
50
- const { src, bindmessage = noop, bindload = noop, binderror = noop } = props
50
+ const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props
51
51
  if (props.style) {
52
52
  warn('The web-view component does not support the style prop.')
53
53
  }
@@ -59,7 +59,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
59
59
  bottom: 0 as number
60
60
  }
61
61
 
62
- const { nodeRef: webViewRef } = useNodesRef<WebView, WebViewProps>(props, ref, {
62
+ const webViewRef = useRef<WebView>(null)
63
+ useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
63
64
  defaultStyle: defaultWebViewStyle
64
65
  })
65
66
 
@@ -1,7 +1,8 @@
1
- import { ViewStyle, ImageResizeMode } from 'react-native'
1
+ import { ViewStyle } from 'react-native'
2
+ import { FunctionComponent } from 'react'
2
3
 
3
4
  type NumberVal = number | `${number}%`
4
- type backgroundPositionList = [ 'left'| 'right', NumberVal, 'top' | 'bottom', NumberVal ] | []
5
+ type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | []
5
6
 
6
7
  export type ExtendedViewStyle = ViewStyle & {
7
8
  backgroundImage?: string
@@ -9,4 +10,9 @@ export type ExtendedViewStyle = ViewStyle & {
9
10
  borderRadius?: string | number
10
11
  backgroundPosition?: backgroundPositionList
11
12
  [key: string]: any
13
+ transform?: {[key: string]: number | string}[]
14
+ }
15
+
16
+ export type ExtendedFunctionComponent = FunctionComponent & {
17
+ isCustomText?: boolean
12
18
  }
@@ -26,6 +26,16 @@ declare module '@mpxjs/utils' {
26
26
  export function isObject (value): value is Object
27
27
  export function error (msg: string, location?: string, e?: any): void
28
28
  export function warn (msg: string, location?: string, e?: any): void
29
+ export function getFocusedNavigation (): {
30
+ insets: {
31
+ top: number
32
+ bottom: number
33
+ left: number
34
+ right: number
35
+ }
36
+ } | undefined
29
37
  }
30
38
 
31
- declare let global: Record<string, any>
39
+ declare let global: {
40
+ __formatValue (value: string): string | number
41
+ } & Record<string, any>
@@ -0,0 +1,248 @@
1
+ import { useEffect, useMemo, useRef } from 'react'
2
+ import { TransformsStyle } from 'react-native'
3
+ import {
4
+ Easing,
5
+ useSharedValue,
6
+ withTiming,
7
+ useAnimatedStyle,
8
+ withSequence,
9
+ withDelay,
10
+ makeMutable,
11
+ cancelAnimation,
12
+ SharedValue,
13
+ WithTimingConfig,
14
+ AnimationCallback
15
+ } from 'react-native-reanimated'
16
+ import { ExtendedViewStyle } from './types/common'
17
+ import type { _ViewProps } from './mpx-view'
18
+
19
+ // type TransformKey = 'translateX' | 'translateY' | 'rotate' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scaleX' | 'scaleY' | 'skewX' | 'skewY'
20
+ // type NormalKey = 'opacity' | 'backgroundColor' | 'width' | 'height' | 'top' | 'right' | 'bottom' | 'left' | 'transformOrigin'
21
+ // type RuleKey = TransformKey | NormalKey
22
+ type AnimatedOption = {
23
+ duration: number
24
+ delay: number
25
+ useNativeDriver: boolean
26
+ timingFunction: 'linear' | 'ease' | 'ease-in' | 'ease-in-out'| 'ease-out'
27
+ transformOrigin: string
28
+ }
29
+ type ExtendWithTimingConfig = WithTimingConfig & {
30
+ delay: number
31
+ }
32
+ export type AnimationStepItem = {
33
+ animatedOption: AnimatedOption
34
+ rules: Map<string, number | string>
35
+ transform: Map<string, number>
36
+ }
37
+ export type AnimationProp = {
38
+ id: number,
39
+ actions: AnimationStepItem[]
40
+ }
41
+
42
+ // 微信 timingFunction 和 RN Easing 对应关系
43
+ const EasingKey = {
44
+ linear: Easing.linear,
45
+ ease: Easing.ease,
46
+ 'ease-in': Easing.in(Easing.ease),
47
+ 'ease-in-out': Easing.inOut(Easing.ease),
48
+ 'ease-out': Easing.out(Easing.ease)
49
+ // 'step-start': '',
50
+ // 'step-end': ''
51
+ }
52
+ const TransformInitial: ExtendedViewStyle = {
53
+ // matrix: 0,
54
+ // matrix3d: 0,
55
+ rotate: '0deg',
56
+ rotateX: '0deg',
57
+ rotateY: '0deg',
58
+ rotateZ: '0deg',
59
+ // rotate3d:[0,0,0]
60
+ scale: 1,
61
+ // scale3d: [1, 1, 1],
62
+ scaleX: 1,
63
+ scaleY: 1,
64
+ // scaleZ: 1,
65
+ skew: 0,
66
+ skewX: '0deg',
67
+ skewY: '0deg',
68
+ translate: 0,
69
+ // translate3d: 0,
70
+ translateX: 0,
71
+ translateY: 0
72
+ // translateZ: 0,
73
+ }
74
+ // 动画默认初始值
75
+ const InitialValue: ExtendedViewStyle = Object.assign({
76
+ opacity: 1,
77
+ backgroundColor: 'transparent',
78
+ width: 0,
79
+ height: 0,
80
+ top: 0,
81
+ right: 0,
82
+ bottom: 0,
83
+ left: 0,
84
+ transformOrigin: ['50%', '50%', 0]
85
+ }, TransformInitial)
86
+ const TransformOrigin = 'transformOrigin'
87
+ // deg 角度
88
+ // const isDeg = (key: RuleKey) => ['rotateX', 'rotateY', 'rotateZ', 'rotate', 'skewX', 'skewY'].includes(key)
89
+ // 背景色
90
+ // const isBg = (key: RuleKey) => key === 'backgroundColor'
91
+ // transform
92
+ const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
93
+
94
+ export default function useAnimationHooks<T, P> (props: _ViewProps) {
95
+ const { style: originalStyle = {}, animation } = props
96
+ // id 标识
97
+ const id = animation?.id || -1
98
+ // 有动画样式的 style key
99
+ const animatedStyleKeys = useSharedValue([] as (string|string[])[])
100
+ const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: Boolean})
101
+ // ** 全量 style prop sharedValue
102
+ // 不能做增量的原因:
103
+ // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
104
+ // 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
105
+ const shareValMap = useMemo(() => {
106
+ return Object.keys(InitialValue).reduce((valMap, key) => {
107
+ const defaultVal = getInitialVal(key, isTransform(key))
108
+ valMap[key] = makeMutable(defaultVal)
109
+ return valMap
110
+ }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
111
+ }, [])
112
+ // ** 获取动画样式prop & 驱动动画
113
+ useEffect(() => {
114
+ if (id === -1) return
115
+ // 更新动画样式 key map
116
+ animatedKeys.current = getAnimatedStyleKeys()
117
+ const keys = Object.keys(animatedKeys.current)
118
+ animatedStyleKeys.value = formatAnimatedKeys([TransformOrigin, ...keys])
119
+ // 驱动动画
120
+ createAnimation(keys)
121
+ }, [id])
122
+ // ** 清空动画
123
+ useEffect(() => {
124
+ return () => {
125
+ Object.values(shareValMap).forEach((value) => {
126
+ cancelAnimation(value)
127
+ })
128
+ }
129
+ }, [])
130
+ // 根据 animation action 创建&驱动动画 key => wi
131
+ function createAnimation (animatedKeys: string[] = []) {
132
+ const actions = animation?.actions || []
133
+ const sequence = {} as { [propName: keyof ExtendedViewStyle]: (string|number)[] }
134
+ const lastValueMap = {} as { [propName: keyof ExtendedViewStyle]: string|number }
135
+ actions.forEach(({ animatedOption, rules, transform }, index) => {
136
+ const { delay, duration, timingFunction, transformOrigin } = animatedOption
137
+ const easing = EasingKey[timingFunction] || Easing.inOut(Easing.quad)
138
+ let needSetCallback = true
139
+ const setTransformOrigin: AnimationCallback = (finished: boolean) => {
140
+ 'worklet'
141
+ // 动画结束后设置下一次transformOrigin
142
+ if (finished) {
143
+ if (index < actions.length - 1) {
144
+ const transformOrigin = actions[index + 1].animatedOption?.transformOrigin
145
+ transformOrigin && (shareValMap[TransformOrigin].value = transformOrigin)
146
+ }
147
+ }
148
+ }
149
+ if (index === 0) {
150
+ // 设置当次中心
151
+ shareValMap[TransformOrigin].value = transformOrigin
152
+ }
153
+ // 添加每个key的多次step动画
154
+ animatedKeys.forEach(key => {
155
+ let toVal = (rules.get(key) || transform.get(key)) as number|string
156
+ // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
157
+ if (!toVal) {
158
+ toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value
159
+ }
160
+ const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
161
+ needSetCallback = false
162
+ if (!sequence[key]) {
163
+ sequence[key] = [animation]
164
+ } else {
165
+ sequence[key].push(animation)
166
+ }
167
+ // 更新一下 lastValueMap
168
+ lastValueMap[key] = toVal
169
+ })
170
+ // 赋值驱动动画
171
+ animatedKeys.forEach((key) => {
172
+ const animations = sequence[key]
173
+ shareValMap[key].value = withSequence(...animations)
174
+ })
175
+ })
176
+ }
177
+ // 创建单个animation
178
+ function getAnimation ({ key, value }: { key: string, value: string|number }, { delay, duration, easing }: ExtendWithTimingConfig, callback?: AnimationCallback) {
179
+ const animation = typeof callback === 'function'
180
+ ? withTiming(value, { duration, easing }, callback)
181
+ : withTiming(value, { duration, easing })
182
+ return delay ? withDelay(delay, animation) : animation
183
+ }
184
+ // 获取初始值(prop style or 默认值)
185
+ function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
186
+ if (isTransform && originalStyle.transform?.length) {
187
+ let initialVal = InitialValue[key]
188
+ // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
189
+ originalStyle.transform.forEach(item => {
190
+ if (item[key] !== undefined) initialVal = item[key]
191
+ })
192
+ return initialVal
193
+ }
194
+ return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key]
195
+ }
196
+ // 循环 animation actions 获取所有有动画的 style prop name
197
+ function getAnimatedStyleKeys () {
198
+ return (animation?.actions || []).reduce((keyMap, action) => {
199
+ const { rules, transform } = action
200
+ const ruleArr = [...rules.keys(), ...transform.keys()]
201
+ ruleArr.forEach(key => {
202
+ if (!keyMap[key]) keyMap[key] = true
203
+ })
204
+ return keyMap
205
+ }, animatedKeys.current)
206
+ }
207
+ // animated key transform 格式化
208
+ function formatAnimatedKeys (keys: string[] = []) {
209
+ const animatedKeys = [] as (string|string[])[]
210
+ const transforms = [] as string[]
211
+ keys.forEach(key => {
212
+ if (isTransform(key)) {
213
+ transforms.push(key)
214
+ } else {
215
+ animatedKeys.push(key)
216
+ }
217
+ })
218
+ if (transforms.length) animatedKeys.push(transforms)
219
+ return animatedKeys
220
+ }
221
+ // transform 数组转对象
222
+ function getTransformObj () {
223
+ 'worklet'
224
+ const transforms = originalStyle.transform || []
225
+ return transforms.reduce((transformObj, item) => {
226
+ return Object.assign(transformObj, item)
227
+ }, {} as { [propName: string]: string | number })
228
+ }
229
+ // ** 生成动画样式
230
+ return useAnimatedStyle(() => {
231
+ // console.info(`useAnimatedStyle styles=`, originalStyle)
232
+ return animatedStyleKeys.value.reduce((styles, key) => {
233
+ // console.info('getAnimationStyles', key, shareValMap[key].value)
234
+ if (Array.isArray(key)) {
235
+ const transformStyle = getTransformObj()
236
+ key.forEach((transformKey) => {
237
+ transformStyle[transformKey] = shareValMap[transformKey].value
238
+ })
239
+ styles.transform = Object.entries(transformStyle).map(([key, value]) => {
240
+ return { [key]: value }
241
+ }) as Extract<'transform', TransformsStyle>
242
+ } else {
243
+ styles[key] = shareValMap[key].value
244
+ }
245
+ return styles
246
+ }, Object.assign({}, originalStyle) as ExtendedViewStyle)
247
+ })
248
+ }
@@ -10,8 +10,7 @@ export type HandlerRef<T, P> = {
10
10
  }
11
11
  }
12
12
 
13
- export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRef<T, P>>, instance:Obj = {}) {
14
- const nodeRef = useRef<T>(null)
13
+ export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRef<T, P>>, nodeRef: RefObject<T>, instance:Obj = {}) {
15
14
  const _props = useRef<P | null>(null)
16
15
  _props.current = props
17
16
 
@@ -26,8 +25,4 @@ export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRe
26
25
  }
27
26
  }
28
27
  })
29
-
30
- return {
31
- nodeRef
32
- }
33
28
  }