@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.
Files changed (42) hide show
  1. package/LICENSE +433 -0
  2. package/lib/dependencies/RequireExternalDependency.js +61 -0
  3. package/lib/file-loader.js +3 -2
  4. package/lib/index.js +60 -15
  5. package/lib/json-compiler/index.js +1 -0
  6. package/lib/parser.js +1 -1
  7. package/lib/platform/json/wx/index.js +43 -25
  8. package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
  9. package/lib/platform/template/wx/component-config/movable-view.js +10 -1
  10. package/lib/platform/template/wx/index.js +2 -1
  11. package/lib/react/LoadAsyncChunkModule.js +74 -0
  12. package/lib/react/index.js +3 -1
  13. package/lib/react/processJSON.js +74 -13
  14. package/lib/react/processScript.js +6 -6
  15. package/lib/react/script-helper.js +100 -41
  16. package/lib/runtime/components/react/context.ts +2 -12
  17. package/lib/runtime/components/react/dist/context.js +1 -1
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
  19. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +135 -0
  20. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
  21. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +58 -301
  22. package/lib/runtime/components/react/dist/mpx-swiper.jsx +27 -53
  23. package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
  24. package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
  25. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  26. package/lib/runtime/components/react/mpx-async-suspense.tsx +180 -0
  27. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
  28. package/lib/runtime/components/react/mpx-movable-view.tsx +60 -350
  29. package/lib/runtime/components/react/mpx-swiper.tsx +25 -53
  30. package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
  31. package/lib/runtime/components/react/types/global.d.ts +15 -0
  32. package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
  33. package/lib/runtime/optionProcessorReact.d.ts +18 -0
  34. package/lib/runtime/optionProcessorReact.js +30 -0
  35. package/lib/script-setup-compiler/index.js +27 -5
  36. package/lib/template-compiler/compiler.js +4 -3
  37. package/lib/utils/dom-tag-config.js +17 -3
  38. package/lib/utils/trans-async-sub-rules.js +19 -0
  39. package/lib/web/script-helper.js +1 -1
  40. package/package.json +4 -4
  41. package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
  42. package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
@@ -7,13 +7,13 @@
7
7
  * ✘ damping
8
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
  */
@@ -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, withTiming } from 'react-native-reanimated';
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, scale = false, 'scale-min': scaleMin = 0.1, 'scale-max': scaleMax = 10, 'scale-value': scaleValue = 1, '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, bindscale, bindchange, onLayout: propsOnLayout } = props;
45
- const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(Object.assign({}, styles.container, style), { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
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
- if (MovableAreaLayout.scaleArea && MovableAreaLayout.registerMovableView && MovableAreaLayout.unregisterMovableView) {
346
- const handleAreaScale = (scaleInfo) => {
347
- 'worklet';
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.scaleArea, viewId, scale, handleScaleUpdate]);
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
- // 使用左上角缩放,计算offset位置的边界范围
391
- const currentScaleVal = currentScale.value;
392
- const scaledWidth = (width || 0) * currentScaleVal;
393
- const scaledHeight = (height || 0) * currentScaleVal;
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 = [maxOffsetX, -left];
181
+ xRange = [maxX, 0];
401
182
  }
402
183
  else {
403
- xRange = [-left, maxOffsetX < 0 ? -left : maxOffsetX];
184
+ xRange = [left === 0 ? 0 : -left, maxX < 0 ? 0 : maxX];
404
185
  }
405
186
  if (MovableAreaLayout.height < scaledHeight) {
406
- yRange = [maxOffsetY, -top];
187
+ yRange = [maxY, 0];
407
188
  }
408
189
  else {
409
- yRange = [-top, maxOffsetY < 0 ? -top : maxOffsetY];
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 resetBoundaryAndCheck = ({ width, height }) => {
195
+ const checkBoundaryPosition = useCallback(({ positionX, positionY }) => {
415
196
  'worklet';
416
- setBoundary({ width, height });
417
- const positionX = offsetX.value;
418
- const positionY = offsetY.value;
419
- const { x: newX, y: newY } = checkBoundaryPosition({ positionX, positionY });
420
- if (positionX !== newX) {
421
- offsetX.value = newX;
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 (positionY !== newY) {
424
- offsetY.value = newY;
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 { y: navigationY = 0 } = navigation?.layout || {};
236
+ const { top: navigationY = 0 } = navigation?.layout || {};
436
237
  layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 };
437
- // 同时更新 layoutValue,供缩放逻辑使用
438
- runOnUI(() => {
439
- layoutValue.value = { width, height };
440
- resetBoundaryAndCheck({ width: width, height: height });
441
- })();
238
+ resetBoundaryAndCheck({ width, height });
442
239
  });
443
- propsOnLayout && propsOnLayout(e);
240
+ props.onLayout && props.onLayout(e);
444
241
  };
445
242
  const extendEvent = useCallback((e, type) => {
446
- const { y: navigationY = 0 } = navigation?.layout || {};
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: currentProps.id || '',
461
- dataset: collectDataset(currentProps),
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, scale, scaleMin, scaleMax, animation, gestureSwitch.current, handleScaleUpdate, MovableAreaLayout.scaleArea]);
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: [{ transformOrigin: 'top left' }, innerStyle, animatedStyles, layoutStyle]
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
- // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
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 checkUnCircular(eventData) {
471
+ function canMove(eventData) {
480
472
  'worklet';
481
473
  const { translation } = eventData;
482
474
  const currentOffset = Math.abs(offset.value);
483
- // 向右滑动swiper
484
- if (translation < 0) {
485
- const boundaryOffset = step.value * (childrenLength.value - 1);
486
- const gestureMovePos = Math.abs(translation) + currentOffset;
487
- return {
488
- // 防止快速连续向右滑动时,手势移动的距离 当前的offset超出边界
489
- targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
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
- const gestureMovePos = currentOffset - translation;
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 computeHalf() {
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
- .onUpdate((e) => {
615
+ .onTouchesMove((e) => {
639
616
  'worklet';
640
617
  if (touchfinish.value)
641
618
  return;
642
- const moveDistance = e[strAbso] - preAbsolutePos.value;
619
+ const touchEventData = e.changedTouches[0];
620
+ const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
643
621
  const eventData = {
644
622
  translation: moveDistance
645
623
  };
646
- // 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
647
- const { half } = computeHalf();
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 = e[strAbso];
635
+ preAbsolutePos.value = touchEventData[strAbso];
669
636
  })
670
- .onFinalize((e) => {
637
+ .onTouchesUp((e) => {
671
638
  'worklet';
672
639
  if (touchfinish.value)
673
640
  return;
674
- const moveDistance = e[strAbso] - moveTranstion.value;
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
  })