@mpxjs/webpack-plugin 2.9.66 → 2.9.69-beta.0

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 (158) hide show
  1. package/lib/dependencies/RecordGlobalComponentsDependency.js +11 -12
  2. package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
  3. package/lib/index.js +29 -8
  4. package/lib/json-compiler/index.js +2 -11
  5. package/lib/loader.js +24 -45
  6. package/lib/native-loader.js +49 -64
  7. package/lib/platform/json/wx/index.js +24 -18
  8. package/lib/platform/style/wx/index.js +49 -47
  9. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  10. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  11. package/lib/platform/template/wx/component-config/index.js +1 -1
  12. package/lib/platform/template/wx/component-config/input.js +1 -1
  13. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  14. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  15. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  16. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  17. package/lib/react/index.js +4 -3
  18. package/lib/react/processJSON.js +5 -13
  19. package/lib/react/processMainScript.js +7 -3
  20. package/lib/react/processScript.js +3 -4
  21. package/lib/react/processStyles.js +14 -4
  22. package/lib/react/processTemplate.js +5 -2
  23. package/lib/resolver/AddModePlugin.js +20 -7
  24. package/lib/runtime/components/react/context.ts +6 -0
  25. package/lib/runtime/components/react/dist/context.js +2 -0
  26. package/lib/runtime/components/react/dist/event.config.js +24 -24
  27. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -174
  28. package/lib/runtime/components/react/dist/mpx-button.jsx +78 -50
  29. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  30. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  31. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  32. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  33. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  34. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  35. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  36. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  37. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  38. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +41 -34
  39. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +30 -39
  40. package/lib/runtime/components/react/dist/mpx-form.jsx +47 -41
  41. package/lib/runtime/components/react/dist/mpx-icon.jsx +9 -17
  42. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  43. package/lib/runtime/components/react/dist/mpx-input.jsx +95 -62
  44. package/lib/runtime/components/react/dist/mpx-label.jsx +24 -28
  45. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +20 -30
  46. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +377 -293
  47. package/lib/runtime/components/react/dist/mpx-navigator.jsx +3 -5
  48. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  49. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  50. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  51. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  52. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  53. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  54. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  55. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +160 -88
  56. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  57. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +39 -34
  58. package/lib/runtime/components/react/dist/mpx-radio.jsx +28 -43
  59. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  60. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  61. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +7 -5
  62. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +77 -51
  63. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  64. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +5 -3
  65. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  66. package/lib/runtime/components/react/dist/mpx-switch.jsx +28 -11
  67. package/lib/runtime/components/react/dist/mpx-text.jsx +12 -11
  68. package/lib/runtime/components/react/dist/mpx-textarea.jsx +9 -4
  69. package/lib/runtime/components/react/dist/mpx-view.jsx +66 -62
  70. package/lib/runtime/components/react/dist/mpx-web-view.jsx +113 -36
  71. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  72. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  73. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  74. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  75. package/lib/runtime/components/react/dist/useAnimationHooks.js +126 -12
  76. package/lib/runtime/components/react/dist/utils.jsx +80 -24
  77. package/lib/runtime/components/react/event.config.ts +25 -26
  78. package/lib/runtime/components/react/getInnerListeners.ts +237 -198
  79. package/lib/runtime/components/react/mpx-button.tsx +105 -58
  80. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  81. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  82. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  83. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  84. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  85. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  86. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  87. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  88. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  89. package/lib/runtime/components/react/mpx-checkbox-group.tsx +77 -51
  90. package/lib/runtime/components/react/mpx-checkbox.tsx +49 -50
  91. package/lib/runtime/components/react/mpx-form.tsx +62 -57
  92. package/lib/runtime/components/react/mpx-icon.tsx +13 -18
  93. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  94. package/lib/runtime/components/react/mpx-input.tsx +139 -117
  95. package/lib/runtime/components/react/mpx-label.tsx +36 -34
  96. package/lib/runtime/components/react/mpx-movable-area.tsx +26 -39
  97. package/lib/runtime/components/react/mpx-movable-view.tsx +455 -337
  98. package/lib/runtime/components/react/mpx-navigator.tsx +3 -9
  99. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  100. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  101. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  102. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  103. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  104. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  105. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  106. package/lib/runtime/components/react/mpx-picker-view-column.tsx +236 -104
  107. package/lib/runtime/components/react/mpx-picker-view.tsx +132 -122
  108. package/lib/runtime/components/react/mpx-radio-group.tsx +77 -54
  109. package/lib/runtime/components/react/mpx-radio.tsx +46 -55
  110. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  111. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  112. package/lib/runtime/components/react/mpx-root-portal.tsx +4 -6
  113. package/lib/runtime/components/react/mpx-scroll-view.tsx +122 -76
  114. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  115. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +6 -4
  116. package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
  117. package/lib/runtime/components/react/mpx-swiper-item.tsx +4 -3
  118. package/lib/runtime/components/react/mpx-switch.tsx +39 -25
  119. package/lib/runtime/components/react/mpx-text.tsx +15 -19
  120. package/lib/runtime/components/react/mpx-textarea.tsx +12 -11
  121. package/lib/runtime/components/react/mpx-view.tsx +93 -77
  122. package/lib/runtime/components/react/mpx-web-view.tsx +117 -55
  123. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  124. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  125. package/lib/runtime/components/react/types/common.ts +2 -0
  126. package/lib/runtime/components/react/types/global.d.ts +5 -17
  127. package/lib/runtime/components/react/useAnimationHooks.ts +127 -18
  128. package/lib/runtime/components/react/useNodesRef.ts +1 -0
  129. package/lib/runtime/components/react/utils.tsx +113 -27
  130. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  131. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  132. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  133. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  134. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  135. package/lib/runtime/optionProcessor.js +7 -38
  136. package/lib/runtime/optionProcessorReact.js +0 -15
  137. package/lib/runtime/swanHelper.wxs +1 -1
  138. package/lib/runtime/utils.js +2 -0
  139. package/lib/style-compiler/index.js +1 -1
  140. package/lib/style-compiler/plugins/scope-id.js +31 -2
  141. package/lib/template-compiler/bind-this.js +7 -2
  142. package/lib/template-compiler/compiler.js +118 -56
  143. package/lib/template-compiler/gen-node-react.js +3 -3
  144. package/lib/template-compiler/index.js +4 -4
  145. package/lib/utils/pre-process-json.js +117 -0
  146. package/lib/web/index.js +5 -4
  147. package/lib/web/processJSON.js +5 -13
  148. package/lib/web/processTemplate.js +2 -2
  149. package/package.json +6 -4
  150. package/LICENSE +0 -433
  151. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  152. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  153. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  154. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  155. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  156. package/lib/runtime/components/react/mpx-image/index.tsx +0 -346
  157. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  158. package/lib/runtime/components/web/event.js +0 -105
@@ -1,27 +1,30 @@
1
1
  /**
2
2
  * ✔ direction
3
- * inertia
4
- * out-of-bounds
3
+ * inertia
4
+ * out-of-bounds
5
5
  * ✔ x
6
6
  * ✔ y
7
7
  * ✘ damping
8
- * friction
8
+ * friction
9
9
  * ✔ disabled
10
- * scale
11
- * scale-min
12
- * scale-max
13
- * scale-value
10
+ * scale
11
+ * scale-min
12
+ * scale-max
13
+ * scale-value
14
14
  * ✘ animation
15
15
  * ✔ bindchange
16
- * bindscale
16
+ * bindscale
17
17
  * ✔ htouchmove
18
18
  * ✔ vtouchmove
19
19
  */
20
- import { useRef, useEffect, forwardRef, useContext, useState, useMemo } from 'react';
21
- import { StyleSheet, Animated, PanResponder } from 'react-native';
22
- import useInnerProps, { getCustomEvent } from './getInnerListeners';
20
+ import { useEffect, forwardRef, useContext, useCallback, useRef, useMemo, createElement } from 'react';
21
+ import { StyleSheet } from 'react-native';
22
+ import { getCustomEvent } from './getInnerListeners';
23
23
  import useNodesRef from './useNodesRef';
24
24
  import { MovableAreaContext } from './context';
25
+ import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject } from './utils';
26
+ import { GestureDetector, Gesture } from 'react-native-gesture-handler';
27
+ import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, useAnimatedReaction, withSpring } from 'react-native-reanimated';
25
28
  const styles = StyleSheet.create({
26
29
  container: {
27
30
  position: 'absolute',
@@ -29,319 +32,400 @@ const styles = StyleSheet.create({
29
32
  top: 0
30
33
  }
31
34
  });
32
- const _MovableView = forwardRef((props, ref) => {
33
- const { children, friction = 7, scale = false, direction = 'none', x = 0, y = 0, style = {}, 'scale-min': scaleMin = 0.1, 'scale-max': scaleMax = 10, 'scale-value': originScaleValue = 1, bindscale, bindchange } = props;
34
- const pan = useRef(new Animated.ValueXY());
35
- const scaleValue = useRef(new Animated.Value(1));
36
- const [transformOrigin, setTransformOrigin] = useState('0% 0%');
37
- const propsRef = useRef({});
35
+ const _MovableView = forwardRef((movableViewProps, ref) => {
36
+ const { textProps, innerProps: props = {} } = splitProps(movableViewProps);
37
+ const movableGestureRef = useRef();
38
38
  const layoutRef = useRef({});
39
- const MovableAreaLayout = useContext(MovableAreaContext);
40
- const movablePosition = useRef({
41
- x: Number(x),
42
- y: Number(y)
39
+ const changeSource = useRef('');
40
+ const hasLayoutRef = useRef(false);
41
+ const propsRef = useRef({});
42
+ propsRef.current = (props || {});
43
+ const { x = 0, y = 0, inertia = false, disabled = false, animation = true, 'out-of-bounds': outOfBounds = false, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, direction = 'none', 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, bindtouchstart, catchtouchstart, bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove, bindtouchend, catchtouchend } = props;
44
+ const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(Object.assign({}, style, styles.container), { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
45
+ const prevSimultaneousHandlersRef = useRef(originSimultaneousHandlers || []);
46
+ const prevWaitForHandlersRef = useRef(waitFor || []);
47
+ const gestureSwitch = useRef(false);
48
+ const { textStyle, innerStyle } = splitStyle(normalStyle);
49
+ const offsetX = useSharedValue(x);
50
+ const offsetY = useSharedValue(y);
51
+ const startPosition = useSharedValue({
52
+ x: 0,
53
+ y: 0
43
54
  });
55
+ const draggableXRange = useSharedValue([0, 0]);
56
+ const draggableYRange = useSharedValue([0, 0]);
57
+ const isMoving = useSharedValue(false);
58
+ const xInertialMotion = useSharedValue(false);
59
+ const yInertialMotion = useSharedValue(false);
60
+ const isFirstTouch = useSharedValue(true);
61
+ const touchEvent = useSharedValue('');
62
+ const MovableAreaLayout = useContext(MovableAreaContext);
63
+ const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
64
+ const waitForHandlers = flatGesture(waitFor);
44
65
  const nodeRef = useRef(null);
45
66
  useNodesRef(props, ref, nodeRef, {
46
- defaultStyle: styles.container
67
+ style: normalStyle,
68
+ gestureRef: movableGestureRef
47
69
  });
48
- let panResponder = {};
49
- const isFirstTouch = useRef(true);
50
- const touchEvent = useRef('');
51
- const initialDistance = useRef(0);
52
- propsRef.current = props;
53
- useEffect(() => {
54
- if (scale && (scaleValue.current._value !== originScaleValue)) {
55
- const clampedScale = Math.min(scaleMax, Math.max(scaleMin, originScaleValue));
56
- Animated.spring(scaleValue.current, {
57
- toValue: clampedScale,
58
- friction,
59
- useNativeDriver: false
60
- }).start(() => {
61
- bindscale && bindscale(getCustomEvent('scale', {}, {
62
- detail: {
63
- x: pan.current.x._value,
64
- y: pan.current.y._value,
65
- scale: clampedScale
66
- },
67
- layoutRef
68
- }, props));
69
- });
70
+ const hasSimultaneousHandlersChanged = prevSimultaneousHandlersRef.current.length !== (originSimultaneousHandlers?.length || 0) ||
71
+ (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]);
72
+ const hasWaitForHandlersChanged = prevWaitForHandlersRef.current.length !== (waitFor?.length || 0) ||
73
+ (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]);
74
+ if (hasSimultaneousHandlersChanged || hasWaitForHandlersChanged) {
75
+ gestureSwitch.current = !gestureSwitch.current;
76
+ }
77
+ prevSimultaneousHandlersRef.current = originSimultaneousHandlers || [];
78
+ prevWaitForHandlersRef.current = waitFor || [];
79
+ const handleTriggerChange = useCallback(({ x, y, type }) => {
80
+ const { bindchange } = propsRef.current;
81
+ if (!bindchange)
82
+ return;
83
+ let source = '';
84
+ if (type !== 'setData') {
85
+ source = getTouchSource(x, y);
70
86
  }
71
- }, [originScaleValue]);
72
- useEffect(() => {
73
- if (movablePosition.current.x !== Number(x) || movablePosition.current.y !== Number(y)) {
74
- const { x: newX, y: newY } = checkBoundaryPosition({
75
- clampedScale: scaleValue.current._value,
76
- width: layoutRef.current.width,
77
- height: layoutRef.current.height,
78
- positionX: Number(x),
79
- positionY: Number(y)
80
- });
81
- movablePosition.current = { x: newX, y: newY };
82
- Animated.spring(pan.current, {
83
- toValue: { x: newX, y: newY },
84
- useNativeDriver: false,
85
- friction
86
- }).start(() => {
87
- bindchange &&
88
- bindchange(getCustomEvent('change', {}, {
89
- detail: {
90
- x: newX,
91
- y: newY,
92
- source: ''
93
- },
94
- layoutRef
95
- }, props));
96
- });
87
+ else {
88
+ changeSource.current = '';
97
89
  }
98
- }, [x, y]);
99
- const handlePanReleaseOrTerminate = () => {
100
- pan.current.flattenOffset();
101
- isFirstTouch.current = true;
102
- initialDistance.current = 0;
103
- const { x, y } = checkBoundaryPosition({
104
- clampedScale: scaleValue.current._value,
105
- width: layoutRef.current.width,
106
- height: layoutRef.current.height,
107
- positionX: pan.current.x._value,
108
- positionY: pan.current.y._value
109
- });
110
- movablePosition.current = {
111
- x,
112
- y
113
- };
114
- const needChange = x !== pan.current.x._value || y !== pan.current.y._value;
115
- Animated.spring(pan.current, {
116
- toValue: { x, y },
117
- friction: 7,
118
- useNativeDriver: false
119
- }).start(() => {
120
- if (needChange) {
121
- bindchange && bindchange(getCustomEvent('change', {}, {
122
- detail: {
123
- x,
124
- y,
125
- source: 'out-of-bounds'
126
- },
127
- layoutRef
128
- }, propsRef.current));
129
- }
130
- });
131
- };
132
- panResponder = useMemo(() => {
133
- return PanResponder.create({
134
- onMoveShouldSetPanResponder: () => !propsRef.current.disabled,
135
- onMoveShouldSetPanResponderCapture: () => !propsRef.current.disabled,
136
- onPanResponderGrant: (e, gestureState) => {
137
- if (gestureState.numberActiveTouches === 1) {
138
- setTransformOrigin('0% 0%');
139
- pan.current.setOffset({
140
- x: direction === 'all' || direction === 'horizontal' ? pan.current.x._value : 0,
141
- y: direction === 'all' || direction === 'vertical' ? pan.current.y._value : 0
142
- });
143
- pan.current.setValue({ x: 0, y: 0 });
144
- }
145
- else {
146
- initialDistance.current = 0;
147
- setTransformOrigin('50% 50%');
148
- }
90
+ bindchange(getCustomEvent('change', {}, {
91
+ detail: {
92
+ x,
93
+ y,
94
+ source
149
95
  },
150
- onPanResponderMove: (e, gestureState) => {
151
- if (gestureState.numberActiveTouches === 2 && scale) {
152
- setTransformOrigin('50% 50%');
153
- const touch1 = e.nativeEvent.touches[0];
154
- const touch2 = e.nativeEvent.touches[1];
155
- const currentTouchDistance = Math.sqrt(Math.pow(touch1.pageX - touch2.pageX, 2) + Math.pow(touch1.pageY - touch2.pageY, 2));
156
- if (!initialDistance.current) {
157
- initialDistance.current = currentTouchDistance;
158
- }
159
- else {
160
- const newScale = currentTouchDistance / initialDistance.current;
161
- const clampedScale = Math.min(scaleMax, Math.max(scaleMin, newScale));
162
- Animated.spring(scaleValue.current, {
163
- toValue: clampedScale,
164
- friction: 7,
165
- useNativeDriver: false
166
- }).start();
167
- bindscale && bindscale(getCustomEvent('scale', e, {
168
- detail: {
169
- x: pan.current.x._value,
170
- y: pan.current.y._value,
171
- scale: clampedScale
172
- },
173
- layoutRef
174
- }, propsRef.current));
175
- }
96
+ layoutRef
97
+ }, propsRef.current));
98
+ }, []);
99
+ useEffect(() => {
100
+ runOnUI(() => {
101
+ if (offsetX.value !== x || offsetY.value !== y) {
102
+ const { x: newX, y: newY } = checkBoundaryPosition({ positionX: Number(x), positionY: Number(y) });
103
+ if (direction === 'horizontal' || direction === 'all') {
104
+ offsetX.value = animation
105
+ ? withSpring(newX, {
106
+ duration: 1500,
107
+ dampingRatio: 0.8
108
+ })
109
+ : newX;
176
110
  }
177
- else if (gestureState.numberActiveTouches === 1) {
178
- if (initialDistance.current) {
179
- return; // Skip processing if it's switching from a double touch
180
- }
181
- setTransformOrigin('0% 0%');
182
- if (isFirstTouch.current) {
183
- touchEvent.current = Math.abs(gestureState.dx) > Math.abs(gestureState.dy) ? 'htouchmove' : 'vtouchmove';
184
- isFirstTouch.current = false;
185
- }
186
- Animated.event([
187
- null,
188
- {
189
- dx: direction === 'all' || direction === 'horizontal' ? pan.current.x : new Animated.Value(0),
190
- dy: direction === 'all' || direction === 'vertical' ? pan.current.y : new Animated.Value(0)
191
- }
192
- ], {
193
- useNativeDriver: false
194
- })(e, gestureState);
195
- movablePosition.current = {
196
- x: pan.current.x.__getValue(),
197
- y: pan.current.y.__getValue()
198
- };
199
- bindchange && bindchange(getCustomEvent('change', e, {
200
- detail: {
201
- x: movablePosition.current.x,
202
- y: movablePosition.current.y,
203
- source: 'touch'
204
- },
205
- layoutRef
206
- }, propsRef.current));
111
+ if (direction === 'vertical' || direction === 'all') {
112
+ offsetY.value = animation
113
+ ? withSpring(newY, {
114
+ duration: 1500,
115
+ dampingRatio: 0.8
116
+ })
117
+ : newY;
207
118
  }
208
- },
209
- onPanResponderRelease: () => {
210
- handlePanReleaseOrTerminate();
211
- },
212
- onPanResponderTerminate: () => {
213
- handlePanReleaseOrTerminate();
119
+ runOnJS(handleTriggerChange)({
120
+ x: newX,
121
+ y: newY,
122
+ type: 'setData'
123
+ });
214
124
  }
125
+ })();
126
+ }, [x, y]);
127
+ useEffect(() => {
128
+ const { width, height } = layoutRef.current;
129
+ if (width && height) {
130
+ resetBoundaryAndCheck({ width, height });
131
+ }
132
+ }, [MovableAreaLayout.height, MovableAreaLayout.width]);
133
+ useAnimatedReaction(() => ({
134
+ offsetX: offsetX.value,
135
+ offsetY: offsetY.value
136
+ }), (currentValue) => {
137
+ const { offsetX, offsetY } = currentValue;
138
+ runOnJS(handleTriggerChange)({
139
+ x: offsetX,
140
+ y: offsetY
215
141
  });
216
- }, [MovableAreaLayout.width, MovableAreaLayout.height]);
217
- const onLayout = () => {
218
- nodeRef.current?.measure((x, y, width, height) => {
219
- layoutRef.current = { x, y, width, height, offsetLeft: 0, offsetTop: 0 };
220
- const clampedScale = Math.min(scaleMax, Math.max(scaleMin, originScaleValue));
221
- const { x: newX, y: nexY } = checkBoundaryPosition({
222
- clampedScale,
223
- width,
224
- height,
225
- positionX: movablePosition.current.x,
226
- positionY: movablePosition.current.y
227
- });
228
- Animated.spring(pan.current, {
229
- toValue: { x: newX, y: nexY },
230
- useNativeDriver: false,
231
- friction
232
- }).start(() => {
233
- movablePosition.current = { x: newX, y: nexY };
234
- bindchange &&
235
- bindchange(getCustomEvent('change', {}, {
236
- detail: {
237
- x: newX,
238
- y: nexY,
239
- source: ''
240
- },
241
- layoutRef
242
- }, props));
243
- });
244
- });
245
- };
246
- const onTouchMove = (e) => {
247
- const { bindhtouchmove, bindvtouchmove, bindtouchmove } = props;
248
- if (touchEvent.current === 'htouchmove') {
249
- bindhtouchmove && bindhtouchmove(e);
142
+ });
143
+ const getTouchSource = useCallback((offsetX, offsetY) => {
144
+ const hasOverBoundary = offsetX < draggableXRange.value[0] || offsetX > draggableXRange.value[1] ||
145
+ offsetY < draggableYRange.value[0] || offsetY > draggableYRange.value[1];
146
+ let source = changeSource.current;
147
+ if (hasOverBoundary) {
148
+ if (isMoving.value) {
149
+ source = 'touch-out-of-bounds';
150
+ }
151
+ else {
152
+ source = 'out-of-bounds';
153
+ }
250
154
  }
251
- else if (touchEvent.current === 'vtouchmove') {
252
- bindvtouchmove && bindvtouchmove(e);
155
+ else {
156
+ if (isMoving.value) {
157
+ source = 'touch';
158
+ }
159
+ else if ((xInertialMotion.value || yInertialMotion.value) && (changeSource.current === 'touch' || changeSource.current === 'friction')) {
160
+ source = 'friction';
161
+ }
253
162
  }
254
- bindtouchmove && bindtouchmove(e);
255
- };
256
- const onCatchTouchMove = (e) => {
257
- const { catchhtouchmove, catchvtouchmove, catchtouchmove } = props;
258
- if (touchEvent.current === 'htouchmove') {
259
- catchhtouchmove && catchhtouchmove(e);
163
+ changeSource.current = source;
164
+ return source;
165
+ }, []);
166
+ const setBoundary = useCallback(({ width, height }) => {
167
+ const top = (style.position === 'absolute' && style.top) || 0;
168
+ const left = (style.position === 'absolute' && style.left) || 0;
169
+ const scaledWidth = width || 0;
170
+ const scaledHeight = height || 0;
171
+ const maxY = MovableAreaLayout.height - scaledHeight - top;
172
+ const maxX = MovableAreaLayout.width - scaledWidth - left;
173
+ let xRange;
174
+ let yRange;
175
+ if (MovableAreaLayout.width < scaledWidth) {
176
+ xRange = [maxX, 0];
260
177
  }
261
- else if (touchEvent.current === 'vtouchmove') {
262
- catchvtouchmove && catchvtouchmove(e);
178
+ else {
179
+ xRange = [left === 0 ? 0 : -left, maxX < 0 ? 0 : maxX];
263
180
  }
264
- catchtouchmove && catchtouchmove(e);
265
- };
266
- const checkBoundaryPosition = ({ clampedScale, width, height, positionX, positionY }) => {
267
- // Calculate scaled element size
268
- const scaledWidth = width * clampedScale;
269
- const scaledHeight = height * clampedScale;
270
- // Calculate the boundary limits
181
+ if (MovableAreaLayout.height < scaledHeight) {
182
+ yRange = [maxY, 0];
183
+ }
184
+ else {
185
+ yRange = [top === 0 ? 0 : -top, maxY < 0 ? 0 : maxY];
186
+ }
187
+ draggableXRange.value = xRange;
188
+ draggableYRange.value = yRange;
189
+ }, [MovableAreaLayout.height, MovableAreaLayout.width, style.position, style.top, style.left]);
190
+ const checkBoundaryPosition = useCallback(({ positionX, positionY }) => {
191
+ 'worklet';
271
192
  let x = positionX;
272
193
  let y = positionY;
273
- // Correct y coordinate
274
- if (scaledHeight > MovableAreaLayout.height) {
275
- if (y >= 0) {
276
- y = 0;
194
+ // 计算边界限制
195
+ if (x > draggableXRange.value[1]) {
196
+ x = draggableXRange.value[1];
197
+ }
198
+ else if (x < draggableXRange.value[0]) {
199
+ x = draggableXRange.value[0];
200
+ }
201
+ if (y > draggableYRange.value[1]) {
202
+ y = draggableYRange.value[1];
203
+ }
204
+ else if (y < draggableYRange.value[0]) {
205
+ y = draggableYRange.value[0];
206
+ }
207
+ return { x, y };
208
+ }, []);
209
+ const resetBoundaryAndCheck = ({ width, height }) => {
210
+ setBoundary({ width, height });
211
+ runOnUI(() => {
212
+ const positionX = offsetX.value;
213
+ const positionY = offsetY.value;
214
+ const { x: newX, y: newY } = checkBoundaryPosition({ positionX, positionY });
215
+ if (positionX !== newX) {
216
+ offsetX.value = newX;
277
217
  }
278
- else if (y < MovableAreaLayout.height - scaledHeight) {
279
- y = MovableAreaLayout.height - scaledHeight;
218
+ if (positionY !== newY) {
219
+ offsetY.value = newY;
280
220
  }
221
+ })();
222
+ };
223
+ const onLayout = (e) => {
224
+ hasLayoutRef.current = true;
225
+ if (hasSelfPercent) {
226
+ const { width, height } = e?.nativeEvent?.layout || {};
227
+ setWidth(width || 0);
228
+ setHeight(height || 0);
281
229
  }
282
- else {
283
- if (y < 0) {
284
- y = 0;
230
+ nodeRef.current?.measure((x, y, width, height) => {
231
+ layoutRef.current = { x, y, width, height, offsetLeft: 0, offsetTop: 0 };
232
+ resetBoundaryAndCheck({ width, height });
233
+ });
234
+ props.onLayout && props.onLayout(e);
235
+ };
236
+ const extendEvent = useCallback((e) => {
237
+ 'worklet';
238
+ const touchArr = [e.changedTouches, e.allTouches];
239
+ touchArr.forEach(touches => {
240
+ touches && touches.forEach((item) => {
241
+ item.pageX = item.absoluteX;
242
+ item.pageY = item.absoluteY;
243
+ });
244
+ });
245
+ e.touches = e.allTouches;
246
+ }, []);
247
+ const gesture = useMemo(() => {
248
+ const handleTriggerStart = (e) => {
249
+ 'worklet';
250
+ extendEvent(e);
251
+ bindtouchstart && runOnJS(bindtouchstart)(e);
252
+ catchtouchstart && runOnJS(catchtouchstart)(e);
253
+ };
254
+ const handleTriggerMove = (e) => {
255
+ 'worklet';
256
+ extendEvent(e);
257
+ const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove;
258
+ const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove;
259
+ if (hasTouchmove) {
260
+ if (touchEvent.value === 'htouchmove') {
261
+ bindhtouchmove && runOnJS(bindhtouchmove)(e);
262
+ }
263
+ else if (touchEvent.value === 'vtouchmove') {
264
+ bindvtouchmove && runOnJS(bindvtouchmove)(e);
265
+ }
266
+ bindtouchmove && runOnJS(bindtouchmove)(e);
285
267
  }
286
- else if (y > MovableAreaLayout.height - scaledHeight) {
287
- y = MovableAreaLayout.height - scaledHeight;
268
+ if (hasCatchTouchmove) {
269
+ if (touchEvent.value === 'htouchmove') {
270
+ catchhtouchmove && runOnJS(catchhtouchmove)(e);
271
+ }
272
+ else if (touchEvent.value === 'vtouchmove') {
273
+ catchvtouchmove && runOnJS(catchvtouchmove)(e);
274
+ }
275
+ catchtouchmove && runOnJS(catchtouchmove)(e);
288
276
  }
289
- }
290
- // Correct x coordinate
291
- if (scaledWidth > MovableAreaLayout.width) {
292
- if (x >= 0) {
293
- x = 0;
277
+ };
278
+ const handleTriggerEnd = (e) => {
279
+ 'worklet';
280
+ extendEvent(e);
281
+ bindtouchend && runOnJS(bindtouchend)(e);
282
+ catchtouchend && runOnJS(catchtouchend)(e);
283
+ };
284
+ const gesturePan = Gesture.Pan()
285
+ .onTouchesDown((e) => {
286
+ 'worklet';
287
+ const changedTouches = e.changedTouches[0] || { x: 0, y: 0 };
288
+ isMoving.value = false;
289
+ startPosition.value = {
290
+ x: changedTouches.x,
291
+ y: changedTouches.y
292
+ };
293
+ handleTriggerStart(e);
294
+ })
295
+ .onTouchesMove((e) => {
296
+ 'worklet';
297
+ isMoving.value = true;
298
+ const changedTouches = e.changedTouches[0] || { x: 0, y: 0 };
299
+ if (isFirstTouch.value) {
300
+ touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove';
301
+ isFirstTouch.value = false;
294
302
  }
295
- else if (x < MovableAreaLayout.width - scaledWidth) {
296
- x = MovableAreaLayout.width - scaledWidth;
303
+ handleTriggerMove(e);
304
+ if (disabled)
305
+ return;
306
+ const changeX = changedTouches.x - startPosition.value.x;
307
+ const changeY = changedTouches.y - startPosition.value.y;
308
+ if (direction === 'horizontal' || direction === 'all') {
309
+ const newX = offsetX.value + changeX;
310
+ if (!outOfBounds) {
311
+ const { x } = checkBoundaryPosition({ positionX: newX, positionY: offsetY.value });
312
+ offsetX.value = x;
313
+ }
314
+ else {
315
+ offsetX.value = newX;
316
+ }
297
317
  }
298
- }
299
- else {
300
- if (x < 0) {
301
- x = 0;
318
+ if (direction === 'vertical' || direction === 'all') {
319
+ const newY = offsetY.value + changeY;
320
+ if (!outOfBounds) {
321
+ const { y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: newY });
322
+ offsetY.value = y;
323
+ }
324
+ else {
325
+ offsetY.value = newY;
326
+ }
302
327
  }
303
- else if (x > MovableAreaLayout.width - scaledWidth) {
304
- x = MovableAreaLayout.width - scaledWidth;
328
+ })
329
+ .onTouchesUp((e) => {
330
+ 'worklet';
331
+ isFirstTouch.value = true;
332
+ isMoving.value = false;
333
+ handleTriggerEnd(e);
334
+ if (disabled)
335
+ return;
336
+ if (!inertia) {
337
+ const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value });
338
+ if (x !== offsetX.value) {
339
+ offsetX.value = animation
340
+ ? withSpring(x, {
341
+ duration: 1500,
342
+ dampingRatio: 0.8
343
+ })
344
+ : x;
345
+ }
346
+ if (y !== offsetY.value) {
347
+ offsetY.value = animation
348
+ ? withSpring(y, {
349
+ duration: 1500,
350
+ dampingRatio: 0.8
351
+ })
352
+ : y;
353
+ }
354
+ }
355
+ })
356
+ .onFinalize((e) => {
357
+ 'worklet';
358
+ if (!inertia || disabled || !animation)
359
+ return;
360
+ isMoving.value = false;
361
+ if (direction === 'horizontal' || direction === 'all') {
362
+ xInertialMotion.value = true;
363
+ offsetX.value = withDecay({
364
+ velocity: e.velocityX / 10,
365
+ rubberBandEffect: outOfBounds,
366
+ clamp: draggableXRange.value
367
+ }, () => {
368
+ xInertialMotion.value = false;
369
+ });
305
370
  }
371
+ if (direction === 'vertical' || direction === 'all') {
372
+ yInertialMotion.value = true;
373
+ offsetY.value = withDecay({
374
+ velocity: e.velocityY / 10,
375
+ rubberBandEffect: outOfBounds,
376
+ clamp: draggableYRange.value
377
+ }, () => {
378
+ yInertialMotion.value = false;
379
+ });
380
+ }
381
+ })
382
+ .withRef(movableGestureRef);
383
+ if (simultaneousHandlers && simultaneousHandlers.length) {
384
+ gesturePan.simultaneousWithExternalGesture(...simultaneousHandlers);
385
+ }
386
+ if (waitForHandlers && waitForHandlers.length) {
387
+ gesturePan.requireExternalGestureToFail(...waitForHandlers);
306
388
  }
389
+ return gesturePan;
390
+ }, [disabled, direction, inertia, outOfBounds, gestureSwitch.current]);
391
+ const animatedStyles = useAnimatedStyle(() => {
307
392
  return {
308
- x,
309
- y
393
+ transform: [
394
+ { translateX: offsetX.value },
395
+ { translateY: offsetY.value }
396
+ ]
310
397
  };
398
+ });
399
+ const injectCatchEvent = (props) => {
400
+ const eventHandlers = {};
401
+ const catchEventList = [
402
+ { name: 'onTouchStart', value: ['catchtouchstart'] },
403
+ { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] },
404
+ { name: 'onTouchEnd', value: ['catchtouchend'] }
405
+ ];
406
+ catchEventList.forEach(event => {
407
+ event.value.forEach(name => {
408
+ if (props[name] && !eventHandlers[event.name]) {
409
+ eventHandlers[event.name] = (e) => {
410
+ e.stopPropagation();
411
+ };
412
+ }
413
+ });
414
+ });
415
+ return eventHandlers;
311
416
  };
312
- const [translateX, translateY] = [pan.current.x, pan.current.y];
313
- const transformStyle = { transform: [{ translateX }, { translateY }, { scale: scaleValue.current }], transformOrigin: transformOrigin };
314
- const hasTouchmove = () => !!props.bindhtouchmove || !!props.bindvtouchmove || !!props.bindtouchmove;
315
- const hasCatchTouchmove = () => !!props.catchhtouchmove || !!props.catchvtouchmove || !!props.catchtouchmove;
316
- const innerProps = useInnerProps(props, {
417
+ const catchEventHandlers = injectCatchEvent(props);
418
+ const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {};
419
+ return createElement(GestureDetector, { gesture: gesture }, createElement(Animated.View, extendObject({
317
420
  ref: nodeRef,
318
- ...panResponder.panHandlers,
319
- onLayout,
320
- ...(hasTouchmove() ? { bindtouchmove: onTouchMove } : {}),
321
- ...(hasCatchTouchmove() ? { catchtouchmove: onCatchTouchMove } : {})
322
- }, [
323
- 'children',
324
- 'style',
325
- 'direction',
326
- 'x',
327
- 'y',
328
- 'scale',
329
- 'disabled',
330
- 'scale-value',
331
- 'scale-min',
332
- 'scale-max',
333
- 'bindchange',
334
- 'bindscale',
335
- 'htouchmove',
336
- 'vtouchmove'
337
- ], { layoutRef });
338
- return (<Animated.View {...innerProps} style={{
339
- ...styles.container,
340
- ...style,
341
- ...transformStyle
342
- }}>
343
- {children}
344
- </Animated.View>);
421
+ onLayout: onLayout,
422
+ style: [innerStyle, animatedStyles, layoutStyle]
423
+ }, catchEventHandlers), wrapChildren(props, {
424
+ hasVarDec,
425
+ varContext: varContextRef.current,
426
+ textStyle,
427
+ textProps
428
+ })));
345
429
  });
346
- _MovableView.displayName = 'mpx-movable-view';
430
+ _MovableView.displayName = 'MpxMovableView';
347
431
  export default _MovableView;