@mpxjs/webpack-plugin 2.10.17-beta.3 → 2.10.17-beta.6

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 (228) hide show
  1. package/lib/config.js +60 -0
  2. package/lib/file-loader.js +4 -1
  3. package/lib/global.d.ts +245 -0
  4. package/lib/index.js +29 -2
  5. package/lib/json-compiler/index.js +13 -4
  6. package/lib/loader.js +4 -0
  7. package/lib/platform/json/wx/index.js +6 -0
  8. package/lib/platform/style/wx/index.js +57 -33
  9. package/lib/platform/template/wx/component-config/ad.js +5 -0
  10. package/lib/platform/template/wx/component-config/button.js +10 -3
  11. package/lib/platform/template/wx/component-config/camera.js +25 -3
  12. package/lib/platform/template/wx/component-config/canvas.js +8 -1
  13. package/lib/platform/template/wx/component-config/cover-image.js +7 -2
  14. package/lib/platform/template/wx/component-config/cover-view.js +3 -1
  15. package/lib/platform/template/wx/component-config/form.js +27 -2
  16. package/lib/platform/template/wx/component-config/image.js +5 -0
  17. package/lib/platform/template/wx/component-config/input.js +11 -1
  18. package/lib/platform/template/wx/component-config/label.js +10 -2
  19. package/lib/platform/template/wx/component-config/map.js +11 -0
  20. package/lib/platform/template/wx/component-config/movable-area.js +4 -1
  21. package/lib/platform/template/wx/component-config/movable-view.js +17 -2
  22. package/lib/platform/template/wx/component-config/navigator.js +26 -0
  23. package/lib/platform/template/wx/component-config/picker-view.js +12 -0
  24. package/lib/platform/template/wx/component-config/picker.js +3 -1
  25. package/lib/platform/template/wx/component-config/progress.js +11 -1
  26. package/lib/platform/template/wx/component-config/rich-text.js +5 -0
  27. package/lib/platform/template/wx/component-config/scroll-view.js +12 -1
  28. package/lib/platform/template/wx/component-config/slider.js +8 -0
  29. package/lib/platform/template/wx/component-config/swiper-item.js +5 -2
  30. package/lib/platform/template/wx/component-config/swiper.js +10 -0
  31. package/lib/platform/template/wx/component-config/text.js +5 -0
  32. package/lib/platform/template/wx/component-config/textarea.js +20 -3
  33. package/lib/platform/template/wx/component-config/unsupported.js +10 -1
  34. package/lib/platform/template/wx/component-config/video.js +10 -0
  35. package/lib/platform/template/wx/index.js +21 -1
  36. package/lib/react/LoadAsyncChunkModule.js +1 -1
  37. package/lib/react/processStyles.js +21 -9
  38. package/lib/react/style-helper.js +76 -13
  39. package/lib/resolver/AddModePlugin.js +23 -8
  40. package/lib/runtime/components/react/animationHooks/index.ts +75 -0
  41. package/lib/runtime/components/react/animationHooks/useAnimationAPIHooks.ts +198 -0
  42. package/lib/runtime/components/react/animationHooks/useTransitionHooks.ts +297 -0
  43. package/lib/runtime/components/react/animationHooks/utils.ts +196 -0
  44. package/lib/runtime/components/react/context.ts +7 -1
  45. package/lib/runtime/components/react/dist/animationHooks/index.d.ts +15 -0
  46. package/lib/runtime/components/react/dist/animationHooks/index.js +67 -0
  47. package/lib/runtime/components/react/dist/animationHooks/useAnimationAPIHooks.d.ts +3 -0
  48. package/lib/runtime/components/react/dist/animationHooks/useAnimationAPIHooks.js +182 -0
  49. package/lib/runtime/components/react/dist/animationHooks/useTransitionHooks.d.ts +3 -0
  50. package/lib/runtime/components/react/dist/animationHooks/useTransitionHooks.js +274 -0
  51. package/lib/runtime/components/react/dist/animationHooks/utils.d.ts +109 -0
  52. package/lib/runtime/components/react/dist/animationHooks/utils.js +150 -0
  53. package/lib/runtime/components/react/dist/context.d.ts +6 -2
  54. package/lib/runtime/components/react/dist/event.config.d.ts +0 -1
  55. package/lib/runtime/components/react/dist/getInnerListeners.d.ts +0 -1
  56. package/lib/runtime/components/react/dist/mpx-async-suspense.d.ts +0 -1
  57. package/lib/runtime/components/react/dist/mpx-button.d.ts +0 -1
  58. package/lib/runtime/components/react/dist/mpx-camera.d.ts +31 -0
  59. package/lib/runtime/components/react/dist/mpx-camera.jsx +236 -0
  60. package/lib/runtime/components/react/dist/mpx-canvas/Bus.d.ts +0 -1
  61. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.d.ts +0 -1
  62. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.d.ts +0 -1
  63. package/lib/runtime/components/react/dist/mpx-canvas/Image.d.ts +0 -1
  64. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.d.ts +0 -1
  65. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.d.ts +0 -1
  66. package/lib/runtime/components/react/dist/mpx-canvas/html.d.ts +0 -1
  67. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts +0 -1
  68. package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts +0 -1
  69. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts +0 -1
  70. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts +0 -1
  71. package/lib/runtime/components/react/dist/mpx-form.d.ts +0 -1
  72. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts +0 -1
  73. package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -1
  74. package/lib/runtime/components/react/dist/mpx-inline-text.d.ts +0 -1
  75. package/lib/runtime/components/react/dist/mpx-input.d.ts +2 -1
  76. package/lib/runtime/components/react/dist/mpx-input.jsx +10 -9
  77. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.d.ts +0 -1
  78. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +7 -2
  79. package/lib/runtime/components/react/dist/mpx-label.d.ts +0 -1
  80. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts +0 -1
  81. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts +0 -1
  82. package/lib/runtime/components/react/dist/mpx-nav.d.ts +0 -1
  83. package/lib/runtime/components/react/dist/mpx-navigator.d.ts +0 -1
  84. package/lib/runtime/components/react/dist/mpx-picker/date.d.ts +0 -1
  85. package/lib/runtime/components/react/dist/mpx-picker/dateData.d.ts +0 -1
  86. package/lib/runtime/components/react/dist/mpx-picker/index.d.ts +0 -1
  87. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.d.ts +0 -1
  88. package/lib/runtime/components/react/dist/mpx-picker/region.d.ts +0 -1
  89. package/lib/runtime/components/react/dist/mpx-picker/regionData.d.ts +0 -1
  90. package/lib/runtime/components/react/dist/mpx-picker/selector.d.ts +0 -1
  91. package/lib/runtime/components/react/dist/mpx-picker/time.d.ts +0 -1
  92. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +0 -1
  93. package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts +0 -1
  94. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts +0 -1
  95. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts +0 -1
  96. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts +0 -1
  97. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts +0 -1
  98. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewFaces.d.ts +0 -1
  99. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewIndicator.d.ts +0 -1
  100. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewMask.d.ts +0 -1
  101. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts +0 -1
  102. package/lib/runtime/components/react/dist/mpx-popup/popupBase.d.ts +0 -1
  103. package/lib/runtime/components/react/dist/mpx-portal/index.d.ts +0 -1
  104. package/lib/runtime/components/react/dist/mpx-portal/portal-host.d.ts +0 -1
  105. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.d.ts +0 -1
  106. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +2 -2
  107. package/lib/runtime/components/react/dist/mpx-progress.d.ts +0 -1
  108. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts +0 -1
  109. package/lib/runtime/components/react/dist/mpx-radio.d.ts +0 -1
  110. package/lib/runtime/components/react/dist/mpx-rich-text/html.d.ts +0 -1
  111. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts +0 -1
  112. package/lib/runtime/components/react/dist/mpx-root-portal.d.ts +0 -1
  113. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts +0 -1
  114. package/lib/runtime/components/react/dist/mpx-simple-text.d.ts +0 -1
  115. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts +0 -1
  116. package/lib/runtime/components/react/dist/mpx-slider.d.ts +0 -1
  117. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts +0 -1
  118. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts +0 -1
  119. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts +0 -1
  120. package/lib/runtime/components/react/dist/mpx-swiper.d.ts +11 -1
  121. package/lib/runtime/components/react/dist/mpx-swiper.jsx +71 -39
  122. package/lib/runtime/components/react/dist/mpx-switch.d.ts +0 -1
  123. package/lib/runtime/components/react/dist/mpx-text.d.ts +0 -1
  124. package/lib/runtime/components/react/dist/mpx-textarea.d.ts +0 -1
  125. package/lib/runtime/components/react/dist/mpx-video.d.ts +0 -1
  126. package/lib/runtime/components/react/dist/mpx-view.d.ts +3 -3
  127. package/lib/runtime/components/react/dist/mpx-view.jsx +22 -8
  128. package/lib/runtime/components/react/dist/mpx-web-view.d.ts +0 -1
  129. package/lib/runtime/components/react/dist/mpx-web-view.jsx +1 -1
  130. package/lib/runtime/components/react/dist/parser.d.ts +0 -1
  131. package/lib/runtime/components/react/dist/useNodesRef.d.ts +0 -1
  132. package/lib/runtime/components/react/dist/utils.d.ts +1 -1
  133. package/lib/runtime/components/react/dist/utils.jsx +34 -13
  134. package/lib/runtime/components/react/mpx-camera.tsx +327 -0
  135. package/lib/runtime/components/react/mpx-input.tsx +15 -9
  136. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +7 -2
  137. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +2 -2
  138. package/lib/runtime/components/react/mpx-swiper.tsx +86 -37
  139. package/lib/runtime/components/react/mpx-view.tsx +27 -12
  140. package/lib/runtime/components/react/mpx-web-view.tsx +1 -1
  141. package/lib/runtime/components/react/tsconfig.json +26 -0
  142. package/lib/runtime/components/react/types/global.d.ts +1 -0
  143. package/lib/runtime/components/react/utils.tsx +34 -16
  144. package/lib/runtime/optionProcessor.js +5 -0
  145. package/lib/runtime/optionProcessorReact.js +7 -0
  146. package/lib/runtime/stringify.wxs +2 -2
  147. package/lib/style-compiler/strip-conditional-loader/rebaseUrl.js +225 -0
  148. package/lib/style-compiler/strip-conditional-loader.js +76 -185
  149. package/lib/template-compiler/compiler.js +1 -3
  150. package/lib/utils/dom-tag-config.js +1 -1
  151. package/lib/utils/string.js +25 -1
  152. package/package.json +6 -4
  153. package/lib/runtime/components/react/dist/context.d.ts.map +0 -1
  154. package/lib/runtime/components/react/dist/event.config.d.ts.map +0 -1
  155. package/lib/runtime/components/react/dist/getInnerListeners.d.ts.map +0 -1
  156. package/lib/runtime/components/react/dist/mpx-async-suspense.d.ts.map +0 -1
  157. package/lib/runtime/components/react/dist/mpx-button.d.ts.map +0 -1
  158. package/lib/runtime/components/react/dist/mpx-canvas/Bus.d.ts.map +0 -1
  159. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.d.ts.map +0 -1
  160. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.d.ts.map +0 -1
  161. package/lib/runtime/components/react/dist/mpx-canvas/Image.d.ts.map +0 -1
  162. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.d.ts.map +0 -1
  163. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.d.ts.map +0 -1
  164. package/lib/runtime/components/react/dist/mpx-canvas/html.d.ts.map +0 -1
  165. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts.map +0 -1
  166. package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts.map +0 -1
  167. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts.map +0 -1
  168. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts.map +0 -1
  169. package/lib/runtime/components/react/dist/mpx-form.d.ts.map +0 -1
  170. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts.map +0 -1
  171. package/lib/runtime/components/react/dist/mpx-image.d.ts.map +0 -1
  172. package/lib/runtime/components/react/dist/mpx-inline-text.d.ts.map +0 -1
  173. package/lib/runtime/components/react/dist/mpx-input.d.ts.map +0 -1
  174. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.d.ts.map +0 -1
  175. package/lib/runtime/components/react/dist/mpx-label.d.ts.map +0 -1
  176. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts.map +0 -1
  177. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts.map +0 -1
  178. package/lib/runtime/components/react/dist/mpx-nav.d.ts.map +0 -1
  179. package/lib/runtime/components/react/dist/mpx-navigator.d.ts.map +0 -1
  180. package/lib/runtime/components/react/dist/mpx-picker/date.d.ts.map +0 -1
  181. package/lib/runtime/components/react/dist/mpx-picker/dateData.d.ts.map +0 -1
  182. package/lib/runtime/components/react/dist/mpx-picker/index.d.ts.map +0 -1
  183. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.d.ts.map +0 -1
  184. package/lib/runtime/components/react/dist/mpx-picker/region.d.ts.map +0 -1
  185. package/lib/runtime/components/react/dist/mpx-picker/regionData.d.ts.map +0 -1
  186. package/lib/runtime/components/react/dist/mpx-picker/selector.d.ts.map +0 -1
  187. package/lib/runtime/components/react/dist/mpx-picker/time.d.ts.map +0 -1
  188. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts.map +0 -1
  189. package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts.map +0 -1
  190. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts.map +0 -1
  191. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts.map +0 -1
  192. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts.map +0 -1
  193. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.d.ts.map +0 -1
  194. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewFaces.d.ts.map +0 -1
  195. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewIndicator.d.ts.map +0 -1
  196. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewMask.d.ts.map +0 -1
  197. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts.map +0 -1
  198. package/lib/runtime/components/react/dist/mpx-popup/popupBase.d.ts.map +0 -1
  199. package/lib/runtime/components/react/dist/mpx-portal/index.d.ts.map +0 -1
  200. package/lib/runtime/components/react/dist/mpx-portal/portal-host.d.ts.map +0 -1
  201. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.d.ts.map +0 -1
  202. package/lib/runtime/components/react/dist/mpx-progress.d.ts.map +0 -1
  203. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts.map +0 -1
  204. package/lib/runtime/components/react/dist/mpx-radio.d.ts.map +0 -1
  205. package/lib/runtime/components/react/dist/mpx-rich-text/html.d.ts.map +0 -1
  206. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts.map +0 -1
  207. package/lib/runtime/components/react/dist/mpx-root-portal.d.ts.map +0 -1
  208. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts.map +0 -1
  209. package/lib/runtime/components/react/dist/mpx-simple-text.d.ts.map +0 -1
  210. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts.map +0 -1
  211. package/lib/runtime/components/react/dist/mpx-slider.d.ts.map +0 -1
  212. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts.map +0 -1
  213. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts.map +0 -1
  214. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts.map +0 -1
  215. package/lib/runtime/components/react/dist/mpx-swiper.d.ts.map +0 -1
  216. package/lib/runtime/components/react/dist/mpx-switch.d.ts.map +0 -1
  217. package/lib/runtime/components/react/dist/mpx-text.d.ts.map +0 -1
  218. package/lib/runtime/components/react/dist/mpx-textarea.d.ts.map +0 -1
  219. package/lib/runtime/components/react/dist/mpx-video.d.ts.map +0 -1
  220. package/lib/runtime/components/react/dist/mpx-view.d.ts.map +0 -1
  221. package/lib/runtime/components/react/dist/mpx-web-view.d.ts.map +0 -1
  222. package/lib/runtime/components/react/dist/parser.d.ts.map +0 -1
  223. package/lib/runtime/components/react/dist/useAnimationHooks.d.ts +0 -33
  224. package/lib/runtime/components/react/dist/useAnimationHooks.d.ts.map +0 -1
  225. package/lib/runtime/components/react/dist/useAnimationHooks.js +0 -289
  226. package/lib/runtime/components/react/dist/useNodesRef.d.ts.map +0 -1
  227. package/lib/runtime/components/react/dist/utils.d.ts.map +0 -1
  228. package/lib/runtime/components/react/useAnimationHooks.ts +0 -320
@@ -0,0 +1,198 @@
1
+ import { useMemo, useRef, useEffect } from 'react'
2
+ import { error, hasOwn } from '@mpxjs/utils'
3
+ import {
4
+ Easing,
5
+ withSequence,
6
+ makeMutable,
7
+ runOnJS,
8
+ useSharedValue,
9
+ useAnimatedStyle,
10
+ cancelAnimation
11
+ } from 'react-native-reanimated'
12
+ import {
13
+ easingKey,
14
+ animationAPIInitialValue,
15
+ percentExp,
16
+ isTransform,
17
+ getInitialVal,
18
+ getAnimation,
19
+ getTransformObj,
20
+ formatAnimatedKeys
21
+ } from './utils'
22
+ import { useRunOnJSCallback } from '../utils'
23
+ import type { NativeSyntheticEvent, TransformsStyle } from 'react-native'
24
+ import type { AnimationCallback, SharedValue, AnimatableValue } from 'react-native-reanimated'
25
+ import type { ExtendedViewStyle } from '../types/common'
26
+ import type { AnimationHooksPropsType } from './utils'
27
+
28
+ export default function useAnimationAPIHooks<T, P> (props: AnimationHooksPropsType) {
29
+ // console.log(`useAnimationAPIHooks, props=`, props)
30
+ const { style: originalStyle = {}, animation, transitionend } = props
31
+ // style变更标识(首次render不执行)
32
+ const animationDeps = useRef(-1)
33
+ // animation API 使用 animation.id 为依赖
34
+ if (animation?.id) {
35
+ animationDeps.current = animation.id
36
+ }
37
+ // 有动画样式的 style key(useAnimatedStyle使用)
38
+ const animatedStyleKeys = useSharedValue([] as (string|string[])[])
39
+ // 记录需要执行动画的 propName
40
+ const animatedKeys = useRef([] as string[])
41
+ // 记录上次style map
42
+ const lastStyleRef = useRef({} as {[propName: keyof ExtendedViewStyle]: number|string})
43
+ // ** 全量 style prop sharedValue
44
+ const shareValMap = useMemo(() => {
45
+ return Object.keys(animationAPIInitialValue).reduce((valMap, key) => {
46
+ const defaultVal = getInitialVal(originalStyle, key)
47
+ valMap[key] = makeMutable(defaultVal)
48
+ return valMap
49
+ }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
50
+ }, [])
51
+ const runOnJSCallbackRef = useRef({})
52
+ if (transitionend) {
53
+ runOnJSCallbackRef.current = {
54
+ transitionend
55
+ }
56
+ }
57
+ const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
58
+ // 设置 lastShareValRef & shareValMap
59
+ function updateStyleVal () {
60
+ Object.keys(shareValMap).forEach(key => {
61
+ let value = originalStyle[key]
62
+ if (isTransform(key)) {
63
+ value = originalStyle.transform
64
+ Object.entries(getTransformObj(value)).forEach(([key, value]) => {
65
+ if (value !== lastStyleRef.current[key]) {
66
+ lastStyleRef.current[key] = value
67
+ shareValMap[key].value = value
68
+ }
69
+ })
70
+ } else {
71
+ if (value !== lastStyleRef.current[key]) {
72
+ lastStyleRef.current[key] = value
73
+ shareValMap[key].value = value
74
+ }
75
+ }
76
+ })
77
+ }
78
+ // 根据 animation action 创建&驱动动画
79
+ function createAnimation (animatedKeys: string[] = []) {
80
+ const actions = animation?.actions || []
81
+ const sequence = {} as { [propName: keyof ExtendedViewStyle]: (string|number)[] }
82
+ const lastValueMap = {} as { [propName: keyof ExtendedViewStyle]: string|number }
83
+ actions.forEach(({ animatedOption, rules, transform }, index) => {
84
+ const { delay, duration, timingFunction, transformOrigin } = animatedOption
85
+ const easing = timingFunction ? easingKey[timingFunction] : Easing.inOut(Easing.quad)
86
+ let needSetCallback = true
87
+ const callback: AnimationCallback = (finished?: boolean, current?: AnimatableValue) => {
88
+ 'worklet'
89
+ // 动画结束后设置下一次transformOrigin
90
+ if (finished) {
91
+ if (index < actions.length - 1) {
92
+ const transformOrigin = actions[index + 1].animatedOption?.transformOrigin
93
+ transformOrigin && (shareValMap.transformOrigin.value = transformOrigin)
94
+ }
95
+ transitionend && runOnJS(runOnJSCallback)('transitionend', finished, current, duration)
96
+ }
97
+ }
98
+ if (index === 0 && transformOrigin) {
99
+ // 设置当次中心
100
+ shareValMap.transformOrigin.value = transformOrigin
101
+ }
102
+ // 添加每个key的多次step动画
103
+ animatedKeys.forEach(key => {
104
+ const shareVal = shareValMap[key].value
105
+ const ruleV = isTransform(key) ? transform.get(key) : rules.get(key)
106
+ // color 设置为 1
107
+ // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
108
+ let toVal = ruleV !== undefined
109
+ ? ruleV
110
+ : index > 0
111
+ ? lastValueMap[key]
112
+ : shareVal
113
+ if (percentExp.test(`${toVal}`) && !percentExp.test(shareVal as string) && !isNaN(+shareVal)) {
114
+ // 获取到的toVal为百分比格式化shareValMap为百分比
115
+ shareValMap[key].value = `${shareVal as number * 100}%`
116
+ } else if (percentExp.test(shareVal as string) && !percentExp.test(toVal as string) && !isNaN(+toVal)) {
117
+ // 初始值为百分比则格式化toVal为百分比
118
+ toVal = `${toVal as number * 100}%`
119
+ } else if (typeof toVal !== typeof shareVal) {
120
+ // 动画起始值和终态值类型不一致报错提示一下
121
+ error(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`)
122
+ }
123
+ // Todo 对齐wx
124
+ const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? callback : undefined)
125
+ needSetCallback = false
126
+ if (!sequence[key]) {
127
+ sequence[key] = [animation]
128
+ } else {
129
+ sequence[key].push(animation)
130
+ }
131
+ // 更新一下 lastValueMap
132
+ lastValueMap[key] = toVal!
133
+ })
134
+ // 赋值驱动动画
135
+ animatedKeys.forEach((key) => {
136
+ const animations = sequence[key]
137
+ shareValMap[key].value = animations.length > 1 ? withSequence(...animations) : animations[0]
138
+ })
139
+ })
140
+ }
141
+ // 循环 animation actions 获取所有有动画的 style prop name
142
+ function getAnimatedStyleKeys () {
143
+ return (animation?.actions || []).reduce((keyMap, action) => {
144
+ const { rules, transform } = action
145
+ const ruleArr = [...rules.keys(), ...transform.keys()]
146
+ ruleArr.forEach(key => {
147
+ keyMap.push(key)
148
+ })
149
+ // console.log('getAnimatedStyleKeys keyMap=', keyMap)
150
+ return keyMap
151
+ }, [] as string[])
152
+ }
153
+ // 获取动画样式&驱动动画
154
+ function startAnimation () {
155
+ // 更新动画样式 key map
156
+ animatedKeys.current = getAnimatedStyleKeys()
157
+ animatedStyleKeys.value = formatAnimatedKeys(['transformOrigin', ...animatedKeys.current])
158
+ // 驱动动画
159
+ createAnimation(animatedKeys.current)
160
+ }
161
+ // ** style 更新
162
+ useEffect(() => {
163
+ // animation api style 更新同步更新 shareVal(默认)
164
+ updateStyleVal()
165
+ }, [originalStyle])
166
+ // ** 获取动画样式prop & 驱动动画
167
+ useEffect(() => {
168
+ if (animationDeps.current <= 0) return
169
+ startAnimation()
170
+ }, [animationDeps.current])
171
+ // ** 清空动画
172
+ useEffect(() => {
173
+ return () => {
174
+ Object.values(shareValMap).forEach((value) => {
175
+ cancelAnimation(value)
176
+ })
177
+ }
178
+ }, [])
179
+ // ** 生成动画样式
180
+ return useAnimatedStyle(() => {
181
+ // console.info(`useAnimatedStyle styles=`, originalStyle)
182
+ return animatedStyleKeys.value.reduce((styles, key) => {
183
+ if (Array.isArray(key)) {
184
+ const transformStyle = getTransformObj(originalStyle.transform || [])
185
+ key.forEach((transformKey) => {
186
+ transformStyle[transformKey] = shareValMap[transformKey].value
187
+ })
188
+ styles.transform = Object.entries(transformStyle).map(([key, value]) => {
189
+ return { [key]: value }
190
+ }) as Extract<'transform', TransformsStyle>
191
+ } else {
192
+ styles[key] = shareValMap[key].value
193
+ }
194
+ // console.log('animationStyle', styles)
195
+ return styles
196
+ }, {} as ExtendedViewStyle)
197
+ })
198
+ }
@@ -0,0 +1,297 @@
1
+ import { hasOwn, dash2hump, error } from '@mpxjs/utils'
2
+ import { useMemo, useRef, useEffect } from 'react'
3
+ import {
4
+ Easing,
5
+ makeMutable,
6
+ runOnJS,
7
+ useSharedValue,
8
+ useAnimatedStyle,
9
+ cancelAnimation
10
+ } from 'react-native-reanimated'
11
+ import {
12
+ easingKey,
13
+ transitionSupportedProperty,
14
+ transformInitial,
15
+ cubicBezierExp,
16
+ secondRegExp,
17
+ percentExp,
18
+ getTransformObj,
19
+ getUnit,
20
+ getInitialVal,
21
+ getAnimation,
22
+ isTransform
23
+ } from './utils'
24
+ import { parseValues, useRunOnJSCallback } from '../utils'
25
+ import type { SharedValue, AnimatableValue, EasingFunction } from 'react-native-reanimated'
26
+ import type { TransformsStyle } from 'react-native'
27
+ import type { ExtendedViewStyle } from '../types/common'
28
+ import type { AnimationHooksPropsType, TransitionMap, TimingFunction } from './utils'
29
+
30
+ type AnimationDataType = {
31
+ property?: string
32
+ duration?: number
33
+ delay?: number
34
+ easing: EasingFunction
35
+ }
36
+ const propName = {
37
+ transition: '',
38
+ transitionDuration: 'duration',
39
+ transitionProperty: 'property',
40
+ transitionTimingFunction: 'easing',
41
+ transitionDelay: 'delay'
42
+ }
43
+ const behaviorExp = /^(allow-discrete|normal)$/
44
+ const defaultValueExp = /^(inherit|initial|revert|revert-layer|unset)$/
45
+ const timingFunctionExp = /^(step-start|step-end|steps)/
46
+ // cubic-bezier 参数解析
47
+ function getBezierParams (str: string) {
48
+ // ease 0.25, 0.1, 0.25, 1.0
49
+ return str.match(cubicBezierExp)?.[1]?.split(',').map(item => +item)
50
+ }
51
+ // 解析 transition-prop
52
+ function parseTransitionSingleProp (vals: string[], property: string) {
53
+ let setDuration = false
54
+ property = propName[property as keyof typeof propName]
55
+ return vals.map(val => {
56
+ // transition-property all
57
+ if (val === 'all') {
58
+ error('[Mpx runtime error]: the value of transition-property is not supported \'all\'')
59
+ return undefined
60
+ }
61
+ // behavior
62
+ if (behaviorExp.test(val)) {
63
+ error('[Mpx runtime error]: transition-behavior is not supported')
64
+ return undefined
65
+ }
66
+ // global values
67
+ if (defaultValueExp.test(val)) {
68
+ error('[Mpx runtime error]: global values is not supported')
69
+ return undefined
70
+ }
71
+ if (timingFunctionExp.test(val)) {
72
+ error('[Mpx runtime error]: the timingFunction in step-start,step-end,steps() is not supported')
73
+ return undefined
74
+ }
75
+ // timingFunction
76
+ if (Object.keys(easingKey).includes(val) || cubicBezierExp.test(val)) {
77
+ const bezierParams = getBezierParams(val)
78
+ return {
79
+ easing: bezierParams?.length ? Easing.bezier(bezierParams[0], bezierParams[1], bezierParams[2], bezierParams[3]) : easingKey[val as TimingFunction] || Easing.inOut(Easing.ease)
80
+ }
81
+ }
82
+ // duration & delay
83
+ if (secondRegExp.test(val)) {
84
+ const newProperty = property || (!setDuration ? 'duration' : 'delay')
85
+ setDuration = true
86
+ // console.log('parseTransitionSingleProp val=', val, property, setDuration)
87
+ return {
88
+ [newProperty]: getUnit(val)
89
+ }
90
+ }
91
+ // property
92
+ return {
93
+ property: dash2hump(val)
94
+ }
95
+ }).filter(item => item !== undefined)
96
+ }
97
+ // transition 解析
98
+ function parseTransitionStyle (originalStyle: ExtendedViewStyle) {
99
+ let transitionData: AnimationDataType[] = []
100
+ Object.entries(originalStyle).filter(arr => arr[0].includes('transition')).forEach(([prop, value]) => {
101
+ if (prop === 'transition') {
102
+ const vals = parseValues(value, ',').map(item => {
103
+ return parseTransitionSingleProp(parseValues(item), prop).reduce((map, subItem) => {
104
+ return Object.assign(map, subItem)
105
+ }, {} as AnimationDataType)
106
+ })
107
+ // console.log(`parseTransitionStyle ${prop}=${value} formatVal=`, vals)
108
+ if (transitionData.length) {
109
+ transitionData = (vals.length > transitionData.length ? vals : transitionData).map((transitionItem, i) => {
110
+ const valItem = vals[i] || {}
111
+ const current = transitionData[i] || {}
112
+ // console.log('parseTransitionStyle current=', current)
113
+ // console.log('parseTransitionStyle valItem=', valItem)
114
+ // console.log('parseTransitionStyle mergeObj=', Object.assign({}, current, valItem))
115
+ return Object.assign({}, current, valItem)
116
+ })
117
+ // console.log(`parseTransitionStyle ${prop}=${value}, transitionData=`, transitionData)
118
+ } else {
119
+ transitionData = vals
120
+ }
121
+ } else {
122
+ const vals = parseTransitionSingleProp(parseValues(value, ','), prop)
123
+ // console.log(`parseTransitionStyle ${prop}=${value} formatVal=`, vals)
124
+ // formatVal [{"property": "transform"}, {"property": "marginLeft"}]
125
+ if (transitionData.length) {
126
+ transitionData = (vals.length > transitionData.length ? vals : transitionData).map((transitionItem, i) => {
127
+ const valItem = vals[i] || vals[vals.length - 1]
128
+ const current = transitionData[i] || transitionData[transitionData.length - 1]
129
+ // console.log('parseTransitionStyle current=', current)
130
+ // console.log('parseTransitionStyle valItem=', valItem)
131
+ // console.log('parseTransitionStyle mergeObj=', Object.assign({}, current, valItem))
132
+ return Object.assign({}, current, valItem)
133
+ })
134
+ // console.log(`parseTransitionStyle ${prop}=${value}, transitionData=`, transitionData)
135
+ } else {
136
+ transitionData = vals as AnimationDataType[]
137
+ }
138
+ // transitionData.push(...vals)
139
+ }
140
+ })
141
+ // console.log(`parseTransitionStyle transitionData=`, transitionData)
142
+ // 从style 中解析的动画数据,结构如下:
143
+ // transitionMap= {"marginLeft": {"delay": 0, "duration": 3000, "easing": []}, "transform": {"delay": 0, "duration": 3000, "easing": []}}
144
+ const transitionMap = transitionData.reduce((acc, cur) => {
145
+ // hasOwn(transitionSupportedProperty, dash2hump(val)) || val === Transform
146
+ const { property = '', duration = 0, delay = 0, easing = Easing.inOut(Easing.ease) } = cur
147
+ if ((hasOwn(transitionSupportedProperty, dash2hump(property)) || property === 'transform') && duration > 0) {
148
+ acc[property] = {
149
+ duration,
150
+ delay,
151
+ easing
152
+ }
153
+ }
154
+ return acc
155
+ }, {} as TransitionMap)
156
+ // console.log(`parseTransitionStyle transitionMap=`, transitionMap)
157
+ return transitionMap
158
+ }
159
+
160
+ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType) {
161
+ // console.log(`useTransitionHooks, props=`, props)
162
+ const { style: originalStyle = {}, transitionend } = props
163
+ // style变更标识(首次render不执行),初始值为0,首次渲染后为1
164
+ const animationDeps = useRef(0)
165
+ // 记录上次style map
166
+ // const lastStyleRef = useRef({} as {[propName: keyof ExtendedViewStyle]: number|string})
167
+ // ** 从 style 中获取动画数据
168
+ const transitionMap = useMemo(() => {
169
+ return parseTransitionStyle(originalStyle)
170
+ }, [])
171
+ // ** style prop sharedValue interpolateOutput: SharedValue<InterpolateOutput>
172
+ const { shareValMap, animatedKeys, animatedKeysShareVal } = useMemo(() => {
173
+ // 记录需要执行动画的 propName
174
+ const animatedKeys = [] as string[]
175
+ const animatedKeysShareVal = [] as (string|string[])[]
176
+ const transforms = [] as string[]
177
+ const shareValMap = Object.keys(transitionMap).reduce((valMap, property) => {
178
+ // const { property } = transition || {}
179
+ if (property === 'transform') {
180
+ Object.keys(originalStyle.transform ? getTransformObj(originalStyle.transform!) : transformInitial).forEach((key) => {
181
+ const defaultVal = getInitialVal(originalStyle, key)
182
+ // console.log(`shareValMap property=${key} defaultVal=${defaultVal}`)
183
+ valMap[key] = makeMutable(defaultVal)
184
+ animatedKeys.push(key)
185
+ transforms.push(key)
186
+ })
187
+ } else if (hasOwn(transitionSupportedProperty, property)) {
188
+ const defaultVal = getInitialVal(originalStyle, property)
189
+ // console.log(`shareValMap property=${property} defaultVal=${defaultVal}`)
190
+ valMap[property] = makeMutable(defaultVal)
191
+ animatedKeys.push(property)
192
+ animatedKeysShareVal.push(property)
193
+ }
194
+ // console.log('shareValMap = ', valMap)
195
+ return valMap
196
+ }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
197
+ if (transforms.length) animatedKeysShareVal.push(transforms)
198
+ return {
199
+ shareValMap,
200
+ animatedKeys,
201
+ animatedKeysShareVal
202
+ }
203
+ }, [])
204
+ // 有动画样式的 style key(useAnimatedStyle使用)
205
+ const animatedStyleKeys = useSharedValue(animatedKeysShareVal)
206
+ const runOnJSCallbackRef = useRef({})
207
+ const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
208
+ // 根据 animation action 创建&驱动动画
209
+ function createAnimation () {
210
+ let transformTransitionendDone = false
211
+ animatedKeys.forEach(key => {
212
+ // console.log(`createAnimation key=${key} originalStyle=`, originalStyle)
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
+ error(`[Mpx runtime error]: Value types of property ${key} must be consistent during the animation`)
232
+ }
233
+ // console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
234
+ const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key]
235
+ // console.log('animationOptions=', { delay, duration, easing })
236
+ let callback
237
+ if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
238
+ runOnJSCallbackRef.current = {
239
+ animationCallback: (duration: number, finished: boolean, current?: AnimatableValue) => {
240
+ transitionend(finished, current, duration)
241
+ }
242
+ }
243
+ callback = (finished?: boolean, current?: AnimatableValue) => {
244
+ 'worklet'
245
+ // 动画结束后设置下一次transformOrigin
246
+ if (finished) {
247
+ runOnJS(runOnJSCallback)('animationCallback', duration, finished, current)
248
+ }
249
+ }
250
+ }
251
+ const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, callback)
252
+ // Todo transform 有多个属性时也仅执行一次 transitionend(对齐wx)
253
+ if (isTransformKey) {
254
+ transformTransitionendDone = true
255
+ }
256
+ shareValMap[key].value = animation
257
+ // console.log(`useTransitionHooks, ${key}=`, animation)
258
+ })
259
+ }
260
+ // ** style 更新
261
+ useEffect(() => {
262
+ // console.log('useEffect originalStyle animationDeps=', animationDeps.current, originalStyle)
263
+ // 首次不执行
264
+ if (!animationDeps.current) {
265
+ animationDeps.current = 1
266
+ return
267
+ }
268
+ createAnimation()
269
+ }, [originalStyle])
270
+ // ** 清空动画
271
+ useEffect(() => {
272
+ return () => {
273
+ Object.values(shareValMap).forEach((value) => {
274
+ cancelAnimation(value)
275
+ })
276
+ }
277
+ }, [])
278
+ // ** 生成动画样式
279
+ return useAnimatedStyle(() => {
280
+ // console.info(`useAnimatedStyle styles=`, originalStyle)
281
+ return animatedStyleKeys.value.reduce((styles, key) => {
282
+ if (Array.isArray(key)) {
283
+ const transformStyle = getTransformObj(originalStyle.transform || [])
284
+ key.forEach((transformKey) => {
285
+ transformStyle[transformKey] = shareValMap[transformKey].value
286
+ })
287
+ styles.transform = Object.entries(transformStyle).map(([key, value]) => {
288
+ return { [key]: value }
289
+ }) as Extract<'transform', TransformsStyle>
290
+ } else {
291
+ styles[key] = shareValMap[key].value
292
+ }
293
+ // console.log('animationStyle', styles)
294
+ return styles
295
+ }, {} as ExtendedViewStyle)
296
+ })
297
+ }
@@ -0,0 +1,196 @@
1
+ import {
2
+ Easing,
3
+ withTiming,
4
+ withDelay
5
+ } from 'react-native-reanimated'
6
+ import type { AnimatableValue, WithTimingConfig, AnimationCallback, EasingFunction } from 'react-native-reanimated'
7
+ import { hasOwn } from '@mpxjs/utils'
8
+ import type { ExtendedViewStyle } from '../types/common'
9
+ import type { _ViewProps } from '../mpx-view'
10
+
11
+ export type TimingFunction = 'linear' | 'ease' | 'ease-in' | 'ease-in-out'| 'ease-out'
12
+
13
+ export type AnimatedOption = {
14
+ duration: number
15
+ delay?: number
16
+ useNativeDriver?: boolean
17
+ timingFunction?: TimingFunction
18
+ transformOrigin?: string
19
+ }
20
+ export type ExtendWithTimingConfig = WithTimingConfig & {
21
+ delay?: number
22
+ }
23
+ export type AnimationStepItem = {
24
+ animatedOption: AnimatedOption
25
+ rules: Map<string, number | string>
26
+ transform: Map<string, number>
27
+ }
28
+ export type AnimationProp = {
29
+ id: number,
30
+ actions: AnimationStepItem[]
31
+ }
32
+
33
+ export type CustomAnimationCallback = (finished?: boolean, current?: AnimatableValue, duration?: number) => void
34
+
35
+ export type TransitionMap = {
36
+ [propName: string]: {
37
+ duration: number
38
+ delay?: number
39
+ easing: EasingFunction
40
+ }
41
+ }
42
+
43
+ export type InterpolateOutput = {
44
+ [propName: string]: string[]
45
+ }
46
+
47
+ export type AnimationHooksPropsType = _ViewProps & { transitionend?: CustomAnimationCallback }
48
+
49
+ // ms s 单位匹配
50
+ export const secondRegExp = /^\s*(\d*(?:\.\d+)?)(s|ms)?\s*$/
51
+ export const cubicBezierExp = /cubic-bezier\(["']?(.*?)["']?\)/
52
+ export const percentExp = /^((-?(\d+(\.\d+)?|\.\d+))%)$/
53
+ // export const PropNameColorExp = /^c|Color$/
54
+ // export const NumberExp = /^((opacity|flex-grow|flex-shrink|gap|left|right|top|bottom)|(.+-(width|height|left|right|top|bottom|radius|spacing|size|gap|index|offset|opacity)))$/
55
+ // export const ColorExp = /^(color|(.+Color))$/
56
+ // transform
57
+ // export const transform = 'transform'
58
+ // export const transformOrigin = 'transformOrigin'
59
+ // export const transition = 'transition'
60
+
61
+ // 微信 timingFunction 和 RN Easing 对应关系
62
+ export const easingKey = {
63
+ linear: Easing.linear,
64
+ ease: Easing.inOut(Easing.ease),
65
+ 'ease-in': Easing.in(Easing.poly(3)),
66
+ 'ease-in-out': Easing.inOut(Easing.poly(3)),
67
+ 'ease-out': Easing.out(Easing.poly(3))
68
+ // 'step-start': '',
69
+ // 'step-end': ''
70
+ }
71
+ export const transformInitial: ExtendedViewStyle = {
72
+ // matrix: 0,
73
+ // matrix3d: 0,
74
+ // rotate: '0deg',
75
+ rotateX: '0deg',
76
+ rotateY: '0deg',
77
+ rotateZ: '0deg',
78
+ // rotate3d:[0,0,0]
79
+ // scale: 1,
80
+ // scale3d: [1, 1, 1],
81
+ scaleX: 1,
82
+ scaleY: 1,
83
+ // scaleZ: 1,
84
+ // skew: 0,
85
+ skewX: '0deg',
86
+ skewY: '0deg',
87
+ // translate: 0,
88
+ // translate3d: 0,
89
+ translateX: 0,
90
+ translateY: 0
91
+ // translateZ: 0,
92
+ }
93
+ // animation api 动画默认初始值
94
+ export const animationAPIInitialValue: ExtendedViewStyle = Object.assign({
95
+ opacity: 1,
96
+ backgroundColor: 'transparent',
97
+ width: 0,
98
+ height: 0,
99
+ top: 0,
100
+ right: 0,
101
+ bottom: 0,
102
+ left: 0,
103
+ transformOrigin: ['50%', '50%', 0]
104
+ }, transformInitial)
105
+ // transition property
106
+ export const transitionSupportedProperty = Object.assign({
107
+ color: 'transparent',
108
+ borderColor: 'transparent',
109
+ borderBottomColor: 'transparent',
110
+ borderLeftColor: 'transparent',
111
+ borderRightColor: 'transparent',
112
+ borderTopColor: 'transparent',
113
+ borderTopLeftRadius: 0,
114
+ borderTopRightRadius: 0,
115
+ borderBottomLeftRadius: 0,
116
+ borderBottomRightRadius: 0,
117
+ borderRadius: 0,
118
+ borderBottomWidth: 0,
119
+ borderLeftWidth: 0,
120
+ borderRightWidth: 0,
121
+ borderTopWidth: 0,
122
+ borderWidth: 0,
123
+ margin: 0,
124
+ marginBottom: 0,
125
+ marginLeft: 0,
126
+ marginRight: 0,
127
+ marginTop: 0,
128
+ marginHorizontal: 0,
129
+ marginVertical: 0,
130
+ maxHeight: 0,
131
+ maxWidth: 0,
132
+ minHeight: 0,
133
+ minWidth: 0,
134
+ padding: 0,
135
+ paddingBottom: 0,
136
+ paddingLeft: 0,
137
+ paddingRight: 0,
138
+ paddingTop: 0,
139
+ paddingHorizontal: 0,
140
+ paddingVertical: 0,
141
+ fontSize: 0, // Todo
142
+ letterSpacing: 0 // Todo
143
+ }, animationAPIInitialValue)
144
+
145
+ // export type PropertyType = keyof transitionSupportedProperty
146
+ // transform
147
+ export const isTransform = (key: string) => hasOwn(transformInitial, key)
148
+ // transform 数组转对象
149
+ export function getTransformObj (transforms: { [propName: string]: string | number }[]) {
150
+ 'worklet'
151
+ return (transforms || []).reduce((transformObj, item) => {
152
+ return Object.assign(transformObj, item)
153
+ }, {} as { [propName: string]: string | number })
154
+ }
155
+ // 获取样式初始值(prop style or 默认值)
156
+ export function getInitialVal (style: ExtendedViewStyle, key: string) {
157
+ if (isTransform(key) && Array.isArray(style.transform)) {
158
+ let initialVal = transitionSupportedProperty[key]
159
+ // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
160
+ style.transform.forEach(item => {
161
+ if (item[key] !== undefined) initialVal = item[key]
162
+ })
163
+ return initialVal
164
+ }
165
+ return style[key] === undefined ? transitionSupportedProperty[key] : style[key]
166
+ }
167
+ // animated key transform 格式化
168
+ export function formatAnimatedKeys (keys: string[]) {
169
+ // console.log('formatAnimatedKeys keys=', keys)
170
+ const animatedKeys = [] as (string|string[])[]
171
+ const transforms = [] as string[]
172
+ keys.forEach(key => {
173
+ if (isTransform(key)) {
174
+ transforms.push(key)
175
+ } else {
176
+ animatedKeys.push(key)
177
+ }
178
+ })
179
+ if (transforms.length) animatedKeys.push(transforms)
180
+ // console.log('formatAnimatedKeys animatedKeys=', animatedKeys)
181
+ return animatedKeys
182
+ }
183
+ // 解析动画时长
184
+ export function getUnit (duration: string) {
185
+ const match = secondRegExp.exec(duration)
186
+ return match ? match[2] === 's' ? +match[1] * 1000 : +match[1] : 0
187
+ }
188
+
189
+ // 根据动画数据创建单个animation
190
+ export function getAnimation ({ key, value }: { key: string, value: string|number }, { delay = 0, duration, easing }: ExtendWithTimingConfig, callback?: AnimationCallback) {
191
+ // console.log('getAnimation', key, value, delay, duration, easing)
192
+ const animation = typeof callback === 'function'
193
+ ? withTiming(value, { duration, easing }, callback)
194
+ : withTiming(value, { duration, easing })
195
+ return delay ? withDelay(delay, animation) : animation
196
+ }