@mpxjs/webpack-plugin 2.10.7-beta.9 → 2.10.8
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.
- package/LICENSE +433 -0
- package/lib/dependencies/RequireExternalDependency.js +61 -0
- package/lib/file-loader.js +3 -2
- package/lib/index.js +60 -15
- package/lib/json-compiler/index.js +1 -0
- package/lib/parser.js +1 -1
- package/lib/platform/json/wx/index.js +43 -25
- package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
- package/lib/platform/template/wx/component-config/movable-view.js +10 -1
- package/lib/platform/template/wx/index.js +2 -1
- package/lib/react/LoadAsyncChunkModule.js +74 -0
- package/lib/react/index.js +3 -1
- package/lib/react/processJSON.js +74 -13
- package/lib/react/processScript.js +6 -6
- package/lib/react/script-helper.js +100 -41
- package/lib/runtime/components/react/context.ts +2 -12
- package/lib/runtime/components/react/dist/context.js +1 -1
- package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
- package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +135 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +58 -301
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +27 -53
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
- package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
- package/lib/runtime/components/react/getInnerListeners.ts +1 -1
- package/lib/runtime/components/react/mpx-async-suspense.tsx +180 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
- package/lib/runtime/components/react/mpx-movable-view.tsx +60 -350
- package/lib/runtime/components/react/mpx-swiper.tsx +25 -53
- package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
- package/lib/runtime/components/react/types/global.d.ts +15 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
- package/lib/runtime/optionProcessorReact.d.ts +18 -0
- package/lib/runtime/optionProcessorReact.js +30 -0
- package/lib/script-setup-compiler/index.js +27 -5
- package/lib/template-compiler/compiler.js +4 -3
- package/lib/utils/dom-tag-config.js +17 -3
- package/lib/utils/trans-async-sub-rules.js +19 -0
- package/lib/web/script-helper.js +1 -1
- package/package.json +4 -4
- package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
- package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* ✘ damping
|
|
8
8
|
* ✘ friction
|
|
9
9
|
* ✔ disabled
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* ✘ scale
|
|
11
|
+
* ✘ scale-min
|
|
12
|
+
* ✘ scale-max
|
|
13
|
+
* ✘ scale-value
|
|
14
14
|
* ✔ animation
|
|
15
15
|
* ✔ bindchange
|
|
16
|
-
*
|
|
16
|
+
* ✘ bindscale
|
|
17
17
|
* ✔ htouchmove
|
|
18
18
|
* ✔ vtouchmove
|
|
19
19
|
*/
|
|
@@ -24,7 +24,7 @@ import useNodesRef from './useNodesRef';
|
|
|
24
24
|
import { MovableAreaContext } from './context';
|
|
25
25
|
import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject, omit, useNavigation } from './utils';
|
|
26
26
|
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
|
|
27
|
-
import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, withSpring
|
|
27
|
+
import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, withSpring } from 'react-native-reanimated';
|
|
28
28
|
import { collectDataset, noop } from '@mpxjs/utils';
|
|
29
29
|
const styles = StyleSheet.create({
|
|
30
30
|
container: {
|
|
@@ -41,8 +41,8 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
41
41
|
const hasLayoutRef = useRef(false);
|
|
42
42
|
const propsRef = useRef({});
|
|
43
43
|
propsRef.current = (props || {});
|
|
44
|
-
const { x = 0, y = 0, inertia = false, disabled = false, animation = true,
|
|
45
|
-
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(Object.assign({}, styles.container
|
|
44
|
+
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', 'disable-event-passthrough': disableEventPassthrough = false, 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, changeThrottleTime = 60, bindtouchstart, catchtouchstart, bindhtouchmove, bindvtouchmove, bindtouchmove, catchhtouchmove, catchvtouchmove, catchtouchmove, bindtouchend, catchtouchend, bindchange } = props;
|
|
45
|
+
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(Object.assign({}, style, styles.container), { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
46
46
|
const navigation = useNavigation();
|
|
47
47
|
const prevSimultaneousHandlersRef = useRef(originSimultaneousHandlers || []);
|
|
48
48
|
const prevWaitForHandlersRef = useRef(waitFor || []);
|
|
@@ -50,8 +50,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
50
50
|
const { textStyle, innerStyle } = splitStyle(normalStyle);
|
|
51
51
|
const offsetX = useSharedValue(x);
|
|
52
52
|
const offsetY = useSharedValue(y);
|
|
53
|
-
const currentScale = useSharedValue(1);
|
|
54
|
-
const layoutValue = useSharedValue({});
|
|
55
53
|
const startPosition = useSharedValue({
|
|
56
54
|
x: 0,
|
|
57
55
|
y: 0
|
|
@@ -102,38 +100,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
102
100
|
layoutRef
|
|
103
101
|
}, propsRef.current));
|
|
104
102
|
}, []);
|
|
105
|
-
const handleTriggerScale = useCallback(({ x, y, scale }) => {
|
|
106
|
-
const { bindscale } = propsRef.current;
|
|
107
|
-
if (!bindscale)
|
|
108
|
-
return;
|
|
109
|
-
bindscale(getCustomEvent('scale', {}, {
|
|
110
|
-
detail: {
|
|
111
|
-
x,
|
|
112
|
-
y,
|
|
113
|
-
scale
|
|
114
|
-
},
|
|
115
|
-
layoutRef
|
|
116
|
-
}, propsRef.current));
|
|
117
|
-
}, []);
|
|
118
|
-
const checkBoundaryPosition = useCallback(({ positionX, positionY }) => {
|
|
119
|
-
'worklet';
|
|
120
|
-
let x = positionX;
|
|
121
|
-
let y = positionY;
|
|
122
|
-
// 计算边界限制
|
|
123
|
-
if (x > draggableXRange.value[1]) {
|
|
124
|
-
x = draggableXRange.value[1];
|
|
125
|
-
}
|
|
126
|
-
else if (x < draggableXRange.value[0]) {
|
|
127
|
-
x = draggableXRange.value[0];
|
|
128
|
-
}
|
|
129
|
-
if (y > draggableYRange.value[1]) {
|
|
130
|
-
y = draggableYRange.value[1];
|
|
131
|
-
}
|
|
132
|
-
else if (y < draggableYRange.value[0]) {
|
|
133
|
-
y = draggableYRange.value[0];
|
|
134
|
-
}
|
|
135
|
-
return { x, y };
|
|
136
|
-
}, []);
|
|
137
103
|
// 节流版本的 change 事件触发
|
|
138
104
|
const handleTriggerChangeThrottled = useCallback(({ x, y, type }) => {
|
|
139
105
|
'worklet';
|
|
@@ -173,193 +139,12 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
173
139
|
}
|
|
174
140
|
})();
|
|
175
141
|
}, [x, y]);
|
|
176
|
-
// 提取通用的缩放边界计算函数
|
|
177
|
-
const calculateScaleBoundaryPosition = useCallback(({ currentOffsetX, currentOffsetY, newScale, width, height }) => {
|
|
178
|
-
'worklet';
|
|
179
|
-
const prevScale = currentScale.value;
|
|
180
|
-
// 计算元素当前中心点(在屏幕上的位置)
|
|
181
|
-
const currentCenterX = currentOffsetX + (width * prevScale) / 2;
|
|
182
|
-
const currentCenterY = currentOffsetY + (height * prevScale) / 2;
|
|
183
|
-
// 实现中心缩放:保持元素中心点不变
|
|
184
|
-
// 计算缩放后为了保持中心点不变需要的新offset位置
|
|
185
|
-
let newOffsetX = currentCenterX - (width * newScale) / 2;
|
|
186
|
-
let newOffsetY = currentCenterY - (height * newScale) / 2;
|
|
187
|
-
// 缩放过程中实时边界检测
|
|
188
|
-
// 计算新的边界范围
|
|
189
|
-
const top = (style.position === 'absolute' && style.top) || 0;
|
|
190
|
-
const left = (style.position === 'absolute' && style.left) || 0;
|
|
191
|
-
const scaledWidth = width * newScale;
|
|
192
|
-
const scaledHeight = height * newScale;
|
|
193
|
-
// 计算新缩放值下的边界限制
|
|
194
|
-
const maxOffsetY = MovableAreaLayout.height - scaledHeight - top;
|
|
195
|
-
const maxOffsetX = MovableAreaLayout.width - scaledWidth - left;
|
|
196
|
-
let xMin, xMax, yMin, yMax;
|
|
197
|
-
if (MovableAreaLayout.width < scaledWidth) {
|
|
198
|
-
xMin = maxOffsetX;
|
|
199
|
-
xMax = -left;
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
xMin = -left;
|
|
203
|
-
xMax = maxOffsetX < 0 ? -left : maxOffsetX;
|
|
204
|
-
}
|
|
205
|
-
if (MovableAreaLayout.height < scaledHeight) {
|
|
206
|
-
yMin = maxOffsetY;
|
|
207
|
-
yMax = -top;
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
yMin = -top;
|
|
211
|
-
yMax = maxOffsetY < 0 ? -top : maxOffsetY;
|
|
212
|
-
}
|
|
213
|
-
// 应用边界限制
|
|
214
|
-
if (newOffsetX > xMax) {
|
|
215
|
-
newOffsetX = xMax;
|
|
216
|
-
}
|
|
217
|
-
else if (newOffsetX < xMin) {
|
|
218
|
-
newOffsetX = xMin;
|
|
219
|
-
}
|
|
220
|
-
if (newOffsetY > yMax) {
|
|
221
|
-
newOffsetY = yMax;
|
|
222
|
-
}
|
|
223
|
-
else if (newOffsetY < yMin) {
|
|
224
|
-
newOffsetY = yMin;
|
|
225
|
-
}
|
|
226
|
-
return { x: newOffsetX, y: newOffsetY };
|
|
227
|
-
}, [MovableAreaLayout.height, MovableAreaLayout.width, style.position, style.top, style.left]);
|
|
228
|
-
// 提取通用的缩放处理函数
|
|
229
|
-
const handleScaleUpdate = useCallback((scaleInfo) => {
|
|
230
|
-
'worklet';
|
|
231
|
-
if (disabled)
|
|
232
|
-
return;
|
|
233
|
-
// 判断缩放方向并计算新的缩放值
|
|
234
|
-
const isZoomingIn = scaleInfo.scale > 1;
|
|
235
|
-
const isZoomingOut = scaleInfo.scale < 1;
|
|
236
|
-
let newScale;
|
|
237
|
-
if (isZoomingIn) {
|
|
238
|
-
// 放大:增加缩放值
|
|
239
|
-
newScale = currentScale.value + (scaleInfo.scale - 1) * 0.5;
|
|
240
|
-
}
|
|
241
|
-
else if (isZoomingOut) {
|
|
242
|
-
// 缩小:减少缩放值
|
|
243
|
-
newScale = currentScale.value - (1 - scaleInfo.scale) * 0.5;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
// 没有缩放变化
|
|
247
|
-
newScale = currentScale.value;
|
|
248
|
-
}
|
|
249
|
-
// 限制缩放值在 scaleMin 和 scaleMax 之间
|
|
250
|
-
newScale = Math.max(scaleMin, Math.min(scaleMax, newScale));
|
|
251
|
-
// 只有当缩放值真正改变时才调整位置
|
|
252
|
-
if (Math.abs(newScale - currentScale.value) > 0.01) {
|
|
253
|
-
// 获取元素尺寸
|
|
254
|
-
const { width = 0, height = 0 } = layoutValue.value;
|
|
255
|
-
if (width > 0 && height > 0) {
|
|
256
|
-
// 使用通用的边界计算函数
|
|
257
|
-
const { x: newOffsetX, y: newOffsetY } = calculateScaleBoundaryPosition({
|
|
258
|
-
currentOffsetX: offsetX.value,
|
|
259
|
-
currentOffsetY: offsetY.value,
|
|
260
|
-
newScale,
|
|
261
|
-
width,
|
|
262
|
-
height
|
|
263
|
-
});
|
|
264
|
-
offsetX.value = newOffsetX;
|
|
265
|
-
offsetY.value = newOffsetY;
|
|
266
|
-
// 更新缩放值
|
|
267
|
-
currentScale.value = newScale;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
currentScale.value = newScale;
|
|
272
|
-
}
|
|
273
|
-
if (bindscale) {
|
|
274
|
-
runOnJS(handleTriggerScale)({
|
|
275
|
-
x: offsetX.value,
|
|
276
|
-
y: offsetY.value,
|
|
277
|
-
scale: newScale
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}, [disabled, scaleMin, scaleMax, bindscale, handleTriggerScale, calculateScaleBoundaryPosition, style.position, style.top, style.left, MovableAreaLayout.height, MovableAreaLayout.width]);
|
|
281
|
-
useEffect(() => {
|
|
282
|
-
runOnUI(() => {
|
|
283
|
-
if (currentScale.value !== scaleValue) {
|
|
284
|
-
// 限制缩放值在 scaleMin 和 scaleMax 之间
|
|
285
|
-
const clampedScale = Math.max(scaleMin, Math.min(scaleMax, scaleValue));
|
|
286
|
-
// 实现中心缩放的位置补偿
|
|
287
|
-
const { width = 0, height = 0 } = layoutValue.value;
|
|
288
|
-
if (width > 0 && height > 0) {
|
|
289
|
-
// 使用通用的边界计算函数
|
|
290
|
-
const { x: newOffsetX, y: newOffsetY } = calculateScaleBoundaryPosition({
|
|
291
|
-
currentOffsetX: offsetX.value,
|
|
292
|
-
currentOffsetY: offsetY.value,
|
|
293
|
-
newScale: clampedScale,
|
|
294
|
-
width,
|
|
295
|
-
height
|
|
296
|
-
});
|
|
297
|
-
// 同时更新缩放值和位置
|
|
298
|
-
if (animation) {
|
|
299
|
-
currentScale.value = withTiming(clampedScale, {
|
|
300
|
-
duration: 1000
|
|
301
|
-
}, () => {
|
|
302
|
-
handleRestBoundaryAndCheck();
|
|
303
|
-
});
|
|
304
|
-
offsetX.value = withTiming(newOffsetX, { duration: 1000 });
|
|
305
|
-
offsetY.value = withTiming(newOffsetY, { duration: 1000 });
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
currentScale.value = clampedScale;
|
|
309
|
-
offsetX.value = newOffsetX;
|
|
310
|
-
offsetY.value = newOffsetY;
|
|
311
|
-
handleRestBoundaryAndCheck();
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
// 如果还没有尺寸信息,只更新缩放值
|
|
316
|
-
if (animation) {
|
|
317
|
-
currentScale.value = withTiming(clampedScale, {
|
|
318
|
-
duration: 1000
|
|
319
|
-
}, () => {
|
|
320
|
-
handleRestBoundaryAndCheck();
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
currentScale.value = clampedScale;
|
|
325
|
-
handleRestBoundaryAndCheck();
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
if (bindscale) {
|
|
329
|
-
runOnJS(handleTriggerScale)({
|
|
330
|
-
x: offsetX.value,
|
|
331
|
-
y: offsetY.value,
|
|
332
|
-
scale: clampedScale
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
})();
|
|
337
|
-
}, [scaleValue, scaleMin, scaleMax, animation]);
|
|
338
|
-
useEffect(() => {
|
|
339
|
-
runOnUI(handleRestBoundaryAndCheck)();
|
|
340
|
-
}, [MovableAreaLayout.height, MovableAreaLayout.width]);
|
|
341
|
-
// 生成唯一 ID
|
|
342
|
-
const viewId = useMemo(() => `movable-view-${Date.now()}-${Math.random()}`, []);
|
|
343
|
-
// 注册到 MovableArea(如果启用了 scale-area)
|
|
344
142
|
useEffect(() => {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
handleScaleUpdate({ scale: scaleInfo.scale });
|
|
349
|
-
};
|
|
350
|
-
const handleAreaScaleEnd = () => {
|
|
351
|
-
'worklet';
|
|
352
|
-
handleRestBoundaryAndCheck();
|
|
353
|
-
};
|
|
354
|
-
MovableAreaLayout.registerMovableView?.(viewId, {
|
|
355
|
-
onScale: scale ? handleAreaScale : noop,
|
|
356
|
-
onScaleEnd: scale ? handleAreaScaleEnd : noop
|
|
357
|
-
});
|
|
358
|
-
return () => {
|
|
359
|
-
MovableAreaLayout.unregisterMovableView?.(viewId);
|
|
360
|
-
};
|
|
143
|
+
const { width, height } = layoutRef.current;
|
|
144
|
+
if (width && height) {
|
|
145
|
+
resetBoundaryAndCheck({ width, height });
|
|
361
146
|
}
|
|
362
|
-
}, [MovableAreaLayout.
|
|
147
|
+
}, [MovableAreaLayout.height, MovableAreaLayout.width]);
|
|
363
148
|
const getTouchSource = useCallback((offsetX, offsetY) => {
|
|
364
149
|
const hasOverBoundary = offsetX < draggableXRange.value[0] || offsetX > draggableXRange.value[1] ||
|
|
365
150
|
offsetY < draggableYRange.value[0] || offsetY > draggableYRange.value[1];
|
|
@@ -384,45 +169,61 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
384
169
|
return source;
|
|
385
170
|
}, []);
|
|
386
171
|
const setBoundary = useCallback(({ width, height }) => {
|
|
387
|
-
'worklet';
|
|
388
172
|
const top = (style.position === 'absolute' && style.top) || 0;
|
|
389
173
|
const left = (style.position === 'absolute' && style.left) || 0;
|
|
390
|
-
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
// offset位置的边界:左上角可以移动的范围
|
|
395
|
-
const maxOffsetY = MovableAreaLayout.height - scaledHeight - top;
|
|
396
|
-
const maxOffsetX = MovableAreaLayout.width - scaledWidth - left;
|
|
174
|
+
const scaledWidth = width || 0;
|
|
175
|
+
const scaledHeight = height || 0;
|
|
176
|
+
const maxY = MovableAreaLayout.height - scaledHeight - top;
|
|
177
|
+
const maxX = MovableAreaLayout.width - scaledWidth - left;
|
|
397
178
|
let xRange;
|
|
398
179
|
let yRange;
|
|
399
180
|
if (MovableAreaLayout.width < scaledWidth) {
|
|
400
|
-
xRange = [
|
|
181
|
+
xRange = [maxX, 0];
|
|
401
182
|
}
|
|
402
183
|
else {
|
|
403
|
-
xRange = [-left,
|
|
184
|
+
xRange = [left === 0 ? 0 : -left, maxX < 0 ? 0 : maxX];
|
|
404
185
|
}
|
|
405
186
|
if (MovableAreaLayout.height < scaledHeight) {
|
|
406
|
-
yRange = [
|
|
187
|
+
yRange = [maxY, 0];
|
|
407
188
|
}
|
|
408
189
|
else {
|
|
409
|
-
yRange = [-top,
|
|
190
|
+
yRange = [top === 0 ? 0 : -top, maxY < 0 ? 0 : maxY];
|
|
410
191
|
}
|
|
411
192
|
draggableXRange.value = xRange;
|
|
412
193
|
draggableYRange.value = yRange;
|
|
413
194
|
}, [MovableAreaLayout.height, MovableAreaLayout.width, style.position, style.top, style.left]);
|
|
414
|
-
const
|
|
195
|
+
const checkBoundaryPosition = useCallback(({ positionX, positionY }) => {
|
|
415
196
|
'worklet';
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
197
|
+
let x = positionX;
|
|
198
|
+
let y = positionY;
|
|
199
|
+
// 计算边界限制
|
|
200
|
+
if (x > draggableXRange.value[1]) {
|
|
201
|
+
x = draggableXRange.value[1];
|
|
202
|
+
}
|
|
203
|
+
else if (x < draggableXRange.value[0]) {
|
|
204
|
+
x = draggableXRange.value[0];
|
|
422
205
|
}
|
|
423
|
-
if (
|
|
424
|
-
|
|
206
|
+
if (y > draggableYRange.value[1]) {
|
|
207
|
+
y = draggableYRange.value[1];
|
|
425
208
|
}
|
|
209
|
+
else if (y < draggableYRange.value[0]) {
|
|
210
|
+
y = draggableYRange.value[0];
|
|
211
|
+
}
|
|
212
|
+
return { x, y };
|
|
213
|
+
}, []);
|
|
214
|
+
const resetBoundaryAndCheck = ({ width, height }) => {
|
|
215
|
+
setBoundary({ width, height });
|
|
216
|
+
runOnUI(() => {
|
|
217
|
+
const positionX = offsetX.value;
|
|
218
|
+
const positionY = offsetY.value;
|
|
219
|
+
const { x: newX, y: newY } = checkBoundaryPosition({ positionX, positionY });
|
|
220
|
+
if (positionX !== newX) {
|
|
221
|
+
offsetX.value = newX;
|
|
222
|
+
}
|
|
223
|
+
if (positionY !== newY) {
|
|
224
|
+
offsetY.value = newY;
|
|
225
|
+
}
|
|
226
|
+
})();
|
|
426
227
|
};
|
|
427
228
|
const onLayout = (e) => {
|
|
428
229
|
hasLayoutRef.current = true;
|
|
@@ -432,20 +233,15 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
432
233
|
setHeight(height || 0);
|
|
433
234
|
}
|
|
434
235
|
nodeRef.current?.measure((x, y, width, height) => {
|
|
435
|
-
const {
|
|
236
|
+
const { top: navigationY = 0 } = navigation?.layout || {};
|
|
436
237
|
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 };
|
|
437
|
-
|
|
438
|
-
runOnUI(() => {
|
|
439
|
-
layoutValue.value = { width, height };
|
|
440
|
-
resetBoundaryAndCheck({ width: width, height: height });
|
|
441
|
-
})();
|
|
238
|
+
resetBoundaryAndCheck({ width, height });
|
|
442
239
|
});
|
|
443
|
-
|
|
240
|
+
props.onLayout && props.onLayout(e);
|
|
444
241
|
};
|
|
445
242
|
const extendEvent = useCallback((e, type) => {
|
|
446
|
-
const {
|
|
243
|
+
const { top: navigationY = 0 } = navigation?.layout || {};
|
|
447
244
|
const touchArr = [e.changedTouches, e.allTouches];
|
|
448
|
-
const currentProps = propsRef.current;
|
|
449
245
|
touchArr.forEach(touches => {
|
|
450
246
|
touches && touches.forEach((item) => {
|
|
451
247
|
item.pageX = item.absoluteX;
|
|
@@ -457,8 +253,8 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
457
253
|
Object.assign(e, {
|
|
458
254
|
touches: type === 'end' ? [] : e.allTouches,
|
|
459
255
|
currentTarget: {
|
|
460
|
-
id:
|
|
461
|
-
dataset: collectDataset(
|
|
256
|
+
id: props.id || '',
|
|
257
|
+
dataset: collectDataset(props),
|
|
462
258
|
offsetLeft: 0,
|
|
463
259
|
offsetTop: 0
|
|
464
260
|
},
|
|
@@ -499,13 +295,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
499
295
|
bindtouchend && bindtouchend(e);
|
|
500
296
|
catchtouchend && catchtouchend(e);
|
|
501
297
|
};
|
|
502
|
-
const handleRestBoundaryAndCheck = () => {
|
|
503
|
-
'worklet';
|
|
504
|
-
const { width, height } = layoutValue.value;
|
|
505
|
-
if (width && height) {
|
|
506
|
-
resetBoundaryAndCheck({ width, height });
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
298
|
const gesture = useMemo(() => {
|
|
510
299
|
const handleTriggerMove = (e) => {
|
|
511
300
|
'worklet';
|
|
@@ -521,8 +310,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
521
310
|
}
|
|
522
311
|
};
|
|
523
312
|
const gesturePan = Gesture.Pan()
|
|
524
|
-
.minPointers(1)
|
|
525
|
-
.maxPointers(1)
|
|
526
313
|
.onTouchesDown((e) => {
|
|
527
314
|
'worklet';
|
|
528
315
|
const changedTouches = e.changedTouches[0] || { x: 0, y: 0 };
|
|
@@ -676,43 +463,13 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
676
463
|
if (waitForHandlers && waitForHandlers.length) {
|
|
677
464
|
gesturePan.requireExternalGestureToFail(...waitForHandlers);
|
|
678
465
|
}
|
|
679
|
-
// 添加缩放手势支持
|
|
680
|
-
if (scale && !MovableAreaLayout.scaleArea) {
|
|
681
|
-
const gesturePinch = Gesture.Pinch()
|
|
682
|
-
.onUpdate((e) => {
|
|
683
|
-
'worklet';
|
|
684
|
-
handleScaleUpdate({ scale: e.scale });
|
|
685
|
-
})
|
|
686
|
-
.onEnd((e) => {
|
|
687
|
-
'worklet';
|
|
688
|
-
if (disabled)
|
|
689
|
-
return;
|
|
690
|
-
// 确保最终缩放值在有效范围内
|
|
691
|
-
const finalScale = Math.max(scaleMin, Math.min(scaleMax, currentScale.value));
|
|
692
|
-
if (finalScale !== currentScale.value) {
|
|
693
|
-
currentScale.value = finalScale;
|
|
694
|
-
if (bindscale) {
|
|
695
|
-
runOnJS(handleTriggerScale)({
|
|
696
|
-
x: offsetX.value,
|
|
697
|
-
y: offsetY.value,
|
|
698
|
-
scale: finalScale
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
// 缩放结束后重新检查边界
|
|
703
|
-
handleRestBoundaryAndCheck();
|
|
704
|
-
});
|
|
705
|
-
// 根据手指数量自动区分手势:一指移动,两指缩放
|
|
706
|
-
return Gesture.Exclusive(gesturePan, gesturePinch);
|
|
707
|
-
}
|
|
708
466
|
return gesturePan;
|
|
709
|
-
}, [disabled, direction, inertia, outOfBounds,
|
|
467
|
+
}, [disabled, direction, inertia, outOfBounds, gestureSwitch.current]);
|
|
710
468
|
const animatedStyles = useAnimatedStyle(() => {
|
|
711
469
|
return {
|
|
712
470
|
transform: [
|
|
713
471
|
{ translateX: offsetX.value },
|
|
714
|
-
{ translateY: offsetY.value }
|
|
715
|
-
{ scale: currentScale.value }
|
|
472
|
+
{ translateY: offsetY.value }
|
|
716
473
|
]
|
|
717
474
|
};
|
|
718
475
|
});
|
|
@@ -749,7 +506,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
749
506
|
const innerProps = useInnerProps(extendObject({}, filterProps, {
|
|
750
507
|
ref: nodeRef,
|
|
751
508
|
onLayout: onLayout,
|
|
752
|
-
style: [
|
|
509
|
+
style: [innerStyle, animatedStyles, layoutStyle]
|
|
753
510
|
}, rewriteCatchEvent()));
|
|
754
511
|
return createElement(GestureDetector, { gesture: gesture }, createElement(Animated.View, innerProps, wrapChildren(props, {
|
|
755
512
|
hasVarDec,
|
|
@@ -125,10 +125,6 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
125
125
|
const moveTranstion = useSharedValue(0);
|
|
126
126
|
// 记录从onBegin 到 onTouchesUp 的时间
|
|
127
127
|
const moveTime = useSharedValue(0);
|
|
128
|
-
// 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
|
|
129
|
-
const anotherDirectionMove = useSharedValue(0);
|
|
130
|
-
// 另一个方向的
|
|
131
|
-
const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase();
|
|
132
128
|
const timerId = useRef(0);
|
|
133
129
|
const intervalTimer = props.interval || 500;
|
|
134
130
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
@@ -409,11 +405,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
409
405
|
}
|
|
410
406
|
}, [children.length]);
|
|
411
407
|
useEffect(() => {
|
|
412
|
-
|
|
413
|
-
// 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
|
|
414
|
-
if (props.current !== currentIndex.value) {
|
|
415
|
-
updateCurrent(props.current || 0, step.value);
|
|
416
|
-
}
|
|
408
|
+
updateCurrent(props.current || 0, step.value);
|
|
417
409
|
}, [props.current]);
|
|
418
410
|
useEffect(() => {
|
|
419
411
|
autoplayShared.value = autoplay;
|
|
@@ -476,26 +468,20 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
476
468
|
targetOffset: -moveToTargetPos
|
|
477
469
|
};
|
|
478
470
|
}
|
|
479
|
-
function
|
|
471
|
+
function canMove(eventData) {
|
|
480
472
|
'worklet';
|
|
481
473
|
const { translation } = eventData;
|
|
482
474
|
const currentOffset = Math.abs(offset.value);
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
canMove: currentOffset < boundaryOffset
|
|
491
|
-
};
|
|
475
|
+
if (!circularShared.value) {
|
|
476
|
+
if (translation < 0) {
|
|
477
|
+
return currentOffset < step.value * (childrenLength.value - 1);
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
return currentOffset > 0;
|
|
481
|
+
}
|
|
492
482
|
}
|
|
493
483
|
else {
|
|
494
|
-
|
|
495
|
-
return {
|
|
496
|
-
targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
|
|
497
|
-
canMove: currentOffset > 0
|
|
498
|
-
};
|
|
484
|
+
return true;
|
|
499
485
|
}
|
|
500
486
|
}
|
|
501
487
|
function handleEnd(eventData) {
|
|
@@ -555,7 +541,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
555
541
|
}
|
|
556
542
|
});
|
|
557
543
|
}
|
|
558
|
-
function
|
|
544
|
+
function handleLongPress() {
|
|
559
545
|
'worklet';
|
|
560
546
|
const currentOffset = Math.abs(offset.value);
|
|
561
547
|
let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value;
|
|
@@ -565,14 +551,6 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
565
551
|
// 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
|
|
566
552
|
const diffOffset = preOffset - currentOffset;
|
|
567
553
|
const half = Math.abs(diffOffset) > step.value / 2;
|
|
568
|
-
return {
|
|
569
|
-
diffOffset,
|
|
570
|
-
half
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
function handleLongPress() {
|
|
574
|
-
'worklet';
|
|
575
|
-
const { diffOffset, half } = computeHalf();
|
|
576
554
|
if (+diffOffset === 0) {
|
|
577
555
|
runOnJS(resumeLoop)();
|
|
578
556
|
}
|
|
@@ -632,30 +610,19 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
632
610
|
runOnJS(pauseLoop)();
|
|
633
611
|
preAbsolutePos.value = e[strAbso];
|
|
634
612
|
moveTranstion.value = e[strAbso];
|
|
635
|
-
anotherDirectionMove.value = e[anotherAbso];
|
|
636
613
|
moveTime.value = new Date().getTime();
|
|
637
614
|
})
|
|
638
|
-
.
|
|
615
|
+
.onTouchesMove((e) => {
|
|
639
616
|
'worklet';
|
|
640
617
|
if (touchfinish.value)
|
|
641
618
|
return;
|
|
642
|
-
const
|
|
619
|
+
const touchEventData = e.changedTouches[0];
|
|
620
|
+
const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
|
|
643
621
|
const eventData = {
|
|
644
622
|
translation: moveDistance
|
|
645
623
|
};
|
|
646
|
-
//
|
|
647
|
-
|
|
648
|
-
if (half) {
|
|
649
|
-
const { selectedIndex } = getTargetPosition(eventData);
|
|
650
|
-
currentIndex.value = selectedIndex;
|
|
651
|
-
}
|
|
652
|
-
// 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
|
|
653
|
-
const { canMove, targetOffset } = checkUnCircular(eventData);
|
|
654
|
-
if (!circularShared.value) {
|
|
655
|
-
if (canMove) {
|
|
656
|
-
offset.value = targetOffset;
|
|
657
|
-
preAbsolutePos.value = e[strAbso];
|
|
658
|
-
}
|
|
624
|
+
// 处理用户一直拖拽到临界点的场景, 不会执行onEnd
|
|
625
|
+
if (!circularShared.value && !canMove(eventData)) {
|
|
659
626
|
return;
|
|
660
627
|
}
|
|
661
628
|
const { isBoundary, resetOffset } = reachBoundary(eventData);
|
|
@@ -665,23 +632,30 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
665
632
|
else {
|
|
666
633
|
offset.value = moveDistance + offset.value;
|
|
667
634
|
}
|
|
668
|
-
preAbsolutePos.value =
|
|
635
|
+
preAbsolutePos.value = touchEventData[strAbso];
|
|
669
636
|
})
|
|
670
|
-
.
|
|
637
|
+
.onTouchesUp((e) => {
|
|
671
638
|
'worklet';
|
|
672
639
|
if (touchfinish.value)
|
|
673
640
|
return;
|
|
674
|
-
const
|
|
641
|
+
const touchEventData = e.changedTouches[0];
|
|
642
|
+
const moveDistance = touchEventData[strAbso] - moveTranstion.value;
|
|
675
643
|
touchfinish.value = true;
|
|
676
644
|
const eventData = {
|
|
677
645
|
translation: moveDistance
|
|
678
646
|
};
|
|
647
|
+
if (childrenLength.value === 1) {
|
|
648
|
+
return handleBackInit();
|
|
649
|
+
}
|
|
650
|
+
// 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
|
|
651
|
+
if (!circularShared.value && !canMove(eventData)) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
679
654
|
const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000;
|
|
680
655
|
if (Math.abs(strVelocity) < longPressRatio) {
|
|
681
656
|
handleLongPress();
|
|
682
657
|
}
|
|
683
658
|
else {
|
|
684
|
-
// 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
|
|
685
659
|
handleEnd(eventData);
|
|
686
660
|
}
|
|
687
661
|
})
|