@mpxjs/webpack-plugin 2.9.69-beta.1 → 2.9.69-beta.10
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/lib/config.js +3 -1
- package/lib/platform/template/wx/index.js +3 -1
- package/lib/react/processScript.js +6 -4
- package/lib/runtime/components/react/context.ts +17 -0
- package/lib/runtime/components/react/dist/context.js +2 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +2 -2
- package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
- package/lib/runtime/components/react/dist/mpx-image.jsx +13 -9
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +65 -61
- package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +93 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
- package/lib/runtime/components/react/dist/mpx-portal.jsx +13 -0
- package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +9 -5
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +13 -7
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +384 -321
- package/lib/runtime/components/react/dist/mpx-view.jsx +16 -20
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +129 -53
- package/lib/runtime/components/react/dist/pickerFaces.js +2 -7
- package/lib/runtime/components/react/dist/useAnimationHooks.js +30 -13
- package/lib/runtime/components/react/dist/utils.jsx +60 -2
- package/lib/runtime/components/react/getInnerListeners.ts +2 -2
- package/lib/runtime/components/react/locale-provider.tsx +83 -0
- package/lib/runtime/components/react/mpx-button.tsx +20 -57
- package/lib/runtime/components/react/mpx-image.tsx +41 -25
- package/lib/runtime/components/react/mpx-picker/time.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +3 -3
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +70 -69
- package/lib/runtime/components/react/mpx-portal/portal-consumer.tsx +32 -0
- package/lib/runtime/components/react/mpx-portal/portal-host.tsx +127 -0
- package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +64 -0
- package/lib/runtime/components/react/mpx-portal.tsx +30 -0
- package/lib/runtime/components/react/mpx-provider.tsx +51 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +10 -8
- package/lib/runtime/components/react/mpx-swiper-item.tsx +13 -7
- package/lib/runtime/components/react/mpx-swiper.tsx +378 -325
- package/lib/runtime/components/react/mpx-view.tsx +19 -22
- package/lib/runtime/components/react/mpx-web-view.tsx +170 -62
- package/lib/runtime/components/react/pickerFaces.ts +2 -7
- package/lib/runtime/components/react/types/global.d.ts +7 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +34 -14
- package/lib/runtime/components/react/utils.tsx +67 -2
- package/lib/template-compiler/compiler.js +1 -1
- package/lib/wxss/loader.js +15 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
2
|
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
|
|
3
|
-
import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS,
|
|
4
|
-
import React, { forwardRef, useRef, useEffect } from 'react';
|
|
3
|
+
import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS, useAnimatedReaction, cancelAnimation } from 'react-native-reanimated';
|
|
4
|
+
import React, { forwardRef, useRef, useEffect, useMemo } from 'react';
|
|
5
5
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
6
6
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
7
7
|
import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren } from './utils';
|
|
@@ -63,21 +63,17 @@ const activeDotStyle = {
|
|
|
63
63
|
};
|
|
64
64
|
const longPressRatio = 100;
|
|
65
65
|
const easeMap = {
|
|
66
|
-
default: Easing.
|
|
66
|
+
default: Easing.inOut(Easing.poly(3)),
|
|
67
67
|
linear: Easing.linear,
|
|
68
68
|
easeInCubic: Easing.in(Easing.cubic),
|
|
69
69
|
easeOutCubic: Easing.out(Easing.cubic),
|
|
70
70
|
easeInOutCubic: Easing.inOut(Easing.cubic)
|
|
71
71
|
};
|
|
72
72
|
const SwiperWrapper = forwardRef((props, ref) => {
|
|
73
|
-
const { 'indicator-dots': showsPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, style = {} } = props;
|
|
74
|
-
const previousMargin = props['previous-margin'] ? parseInt(props['previous-margin']) : 0;
|
|
75
|
-
const nextMargin = props['next-margin'] ? parseInt(props['next-margin']) : 0;
|
|
73
|
+
const { 'indicator-dots': showsPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, style = {}, autoplay = false, circular = false } = props;
|
|
76
74
|
const easeingFunc = props['easing-function'] || 'default';
|
|
77
75
|
const easeDuration = props.duration || 500;
|
|
78
76
|
const horizontal = props.vertical !== undefined ? !props.vertical : true;
|
|
79
|
-
// 默认前后补位的元素个数
|
|
80
|
-
const patchElementNum = props.circular ? (previousMargin ? 2 : 1) : 0;
|
|
81
77
|
const nodeRef = useRef(null);
|
|
82
78
|
useNodesRef(props, ref, nodeRef, {});
|
|
83
79
|
// 计算transfrom之类的
|
|
@@ -90,21 +86,31 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
90
86
|
});
|
|
91
87
|
const { textStyle } = splitStyle(normalStyle);
|
|
92
88
|
const { textProps } = splitProps(props);
|
|
89
|
+
const preMargin = props['previous-margin'] ? global.__formatValue(props['previous-margin']) : 0;
|
|
90
|
+
const nextMargin = props['next-margin'] ? global.__formatValue(props['next-margin']) : 0;
|
|
91
|
+
const preMarginShared = useSharedValue(preMargin);
|
|
92
|
+
const nextMarginShared = useSharedValue(nextMargin);
|
|
93
|
+
const autoplayShared = useSharedValue(autoplay);
|
|
94
|
+
// 默认前后补位的元素个数
|
|
95
|
+
const patchElmNum = circular ? (preMargin ? 2 : 1) : 0;
|
|
96
|
+
const patchElmNumShared = useSharedValue(patchElmNum);
|
|
97
|
+
const circularShared = useSharedValue(circular);
|
|
93
98
|
const children = Array.isArray(props.children) ? props.children.filter(child => child) : (props.children ? [props.children] : []);
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
99
|
+
// 对有变化的变量,在worklet中只能使用sharedValue变量,useRef不能更新
|
|
100
|
+
const childrenLength = useSharedValue(children.length);
|
|
101
|
+
const initWidth = typeof normalStyle?.width === 'number' ? normalStyle.width - preMargin - nextMargin : normalStyle.width;
|
|
102
|
+
const initHeight = typeof normalStyle?.height === 'number' ? normalStyle.height - preMargin - nextMargin : normalStyle.height;
|
|
103
|
+
const dir = horizontal === false ? 'y' : 'x';
|
|
104
|
+
const pstep = dir === 'x' ? initWidth : initHeight;
|
|
98
105
|
const initStep = isNaN(pstep) ? 0 : pstep;
|
|
99
|
-
// 每个元素的宽度 or
|
|
106
|
+
// 每个元素的宽度 or 高度,有固定值直接初始化无则0
|
|
100
107
|
const step = useSharedValue(initStep);
|
|
101
|
-
const totalElements = useSharedValue(children.length);
|
|
102
108
|
// 记录选中元素的索引值
|
|
103
|
-
const currentIndex = useSharedValue(0);
|
|
109
|
+
const currentIndex = useSharedValue(props.current || 0);
|
|
110
|
+
// const initOffset = getOffset(props.current || 0, initStep)
|
|
104
111
|
// 记录元素的偏移量
|
|
105
|
-
const offset = useSharedValue(0);
|
|
106
|
-
const strAbso = 'absolute' + dir.
|
|
107
|
-
const arrPages = renderItems();
|
|
112
|
+
const offset = useSharedValue(getOffset(props.current || 0, initStep));
|
|
113
|
+
const strAbso = 'absolute' + dir.toUpperCase();
|
|
108
114
|
// 标识手指触摸和抬起, 起点在onBegin
|
|
109
115
|
const touchfinish = useSharedValue(true);
|
|
110
116
|
// 记录上一帧的绝对定位坐标
|
|
@@ -114,10 +120,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
114
120
|
// 记录从onBegin 到 onTouchesUp 的时间
|
|
115
121
|
const moveTime = useSharedValue(0);
|
|
116
122
|
const timerId = useRef(0);
|
|
117
|
-
// 用户点击未移动状态下,记录用户上一次操作的transtion 的 direction
|
|
118
|
-
const customTrans = useSharedValue(0);
|
|
119
123
|
const intervalTimer = props.interval || 500;
|
|
120
|
-
totalElements.value = children.length;
|
|
121
124
|
const {
|
|
122
125
|
// 存储layout布局信息
|
|
123
126
|
layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef, onLayout: onWrapperLayout });
|
|
@@ -140,22 +143,20 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
140
143
|
], { layoutRef: layoutRef });
|
|
141
144
|
function onWrapperLayout(e) {
|
|
142
145
|
const { width, height } = e.nativeEvent.layout;
|
|
143
|
-
const realWidth = dir
|
|
144
|
-
const realHeight = dir
|
|
145
|
-
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
pauseLoop();
|
|
151
|
-
resumeLoop();
|
|
146
|
+
const realWidth = dir === 'x' ? width - preMargin - nextMargin : width;
|
|
147
|
+
const realHeight = dir === 'y' ? height - preMargin - nextMargin : height;
|
|
148
|
+
const iStep = dir === 'x' ? realWidth : realHeight;
|
|
149
|
+
if (iStep !== step.value) {
|
|
150
|
+
step.value = iStep;
|
|
151
|
+
updateCurrent(props.current || 0, iStep);
|
|
152
|
+
updateAutoplay();
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
const dotAnimatedStyle = useAnimatedStyle(() => {
|
|
155
156
|
if (!step.value)
|
|
156
157
|
return {};
|
|
157
158
|
const dotStep = dotCommonStyle.width + dotCommonStyle.marginRight + dotCommonStyle.marginLeft;
|
|
158
|
-
if (dir
|
|
159
|
+
if (dir === 'x') {
|
|
159
160
|
return { transform: [{ translateX: currentIndex.value * dotStep }] };
|
|
160
161
|
}
|
|
161
162
|
else {
|
|
@@ -163,17 +164,17 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
163
164
|
}
|
|
164
165
|
});
|
|
165
166
|
function renderPagination() {
|
|
166
|
-
if (
|
|
167
|
+
if (children.length <= 1)
|
|
167
168
|
return null;
|
|
168
169
|
const activeColor = activeDotColor || '#007aff';
|
|
169
170
|
const unActionColor = dotColor || 'rgba(0,0,0,.2)';
|
|
170
171
|
// 正常渲染所有dots
|
|
171
172
|
const dots = [];
|
|
172
|
-
for (let i = 0; i <
|
|
173
|
+
for (let i = 0; i < children.length; i++) {
|
|
173
174
|
dots.push(<View style={[dotCommonStyle, { backgroundColor: unActionColor }]} key={i}></View>);
|
|
174
175
|
}
|
|
175
|
-
return (<View pointerEvents="none" style={styles['pagination_' + dir
|
|
176
|
-
<View style={[styles['pagerWrapper' + dir
|
|
176
|
+
return (<View pointerEvents="none" style={styles['pagination_' + dir]}>
|
|
177
|
+
<View style={[styles['pagerWrapper' + dir]]}>
|
|
177
178
|
<Animated.View style={[
|
|
178
179
|
dotCommonStyle,
|
|
179
180
|
activeDotStyle,
|
|
@@ -190,87 +191,62 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
190
191
|
</View>);
|
|
191
192
|
}
|
|
192
193
|
function renderItems() {
|
|
193
|
-
const
|
|
194
|
-
return dir.value === 'x' ? { width: step.value, height: '100%' } : { width: '100%', height: step.value };
|
|
195
|
-
});
|
|
194
|
+
const intLen = children.length;
|
|
196
195
|
let renderChild = children.slice();
|
|
197
|
-
if (
|
|
196
|
+
if (circular && intLen > 1) {
|
|
198
197
|
// 最前面加最后一个元素
|
|
199
|
-
const lastChild = React.cloneElement(children[
|
|
198
|
+
const lastChild = React.cloneElement(children[intLen - 1], { key: 'clone0' });
|
|
200
199
|
// 最后面加第一个元素
|
|
201
|
-
const firstChild = React.cloneElement(children[0]);
|
|
202
|
-
if (
|
|
203
|
-
const lastChild1 = React.cloneElement(children[
|
|
204
|
-
const firstChild1 = React.cloneElement(children[1]);
|
|
200
|
+
const firstChild = React.cloneElement(children[0], { key: 'clone1' });
|
|
201
|
+
if (preMargin) {
|
|
202
|
+
const lastChild1 = React.cloneElement(children[intLen - 2], { key: 'clone2' });
|
|
203
|
+
const firstChild1 = React.cloneElement(children[1], { key: 'clone3' });
|
|
205
204
|
renderChild = [lastChild1, lastChild].concat(renderChild).concat([firstChild, firstChild1]);
|
|
206
205
|
}
|
|
207
206
|
else {
|
|
208
207
|
renderChild = [lastChild].concat(renderChild).concat([firstChild]);
|
|
209
208
|
}
|
|
210
209
|
}
|
|
211
|
-
const
|
|
210
|
+
const arrChildren = renderChild.map((child, index) => {
|
|
212
211
|
const extraStyle = {};
|
|
213
|
-
if (index === 0 && !
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
if (index === 0 && !circular) {
|
|
213
|
+
preMargin && dir === 'x' && (extraStyle.marginLeft = preMargin);
|
|
214
|
+
preMargin && dir === 'y' && (extraStyle.marginTop = preMargin);
|
|
216
215
|
}
|
|
217
|
-
if (index ===
|
|
218
|
-
nextMargin && dir
|
|
219
|
-
nextMargin && dir
|
|
216
|
+
if (index === intLen - 1 && !circular) {
|
|
217
|
+
nextMargin && dir === 'x' && (extraStyle.marginRight = nextMargin);
|
|
218
|
+
nextMargin && dir === 'y' && (extraStyle.marginBottom = nextMargin);
|
|
220
219
|
}
|
|
220
|
+
// 业务swiper-item自己生成key,内部添加的元素自定义key
|
|
221
221
|
const newChild = React.cloneElement(child, {
|
|
222
222
|
itemIndex: index,
|
|
223
|
-
customStyle:
|
|
224
|
-
key: 'page' + index
|
|
223
|
+
customStyle: extraStyle
|
|
225
224
|
});
|
|
226
225
|
return newChild;
|
|
227
226
|
});
|
|
228
227
|
const contextValue = {
|
|
229
228
|
offset,
|
|
230
229
|
step,
|
|
231
|
-
scale: props.scale
|
|
230
|
+
scale: props.scale,
|
|
231
|
+
dir
|
|
232
232
|
};
|
|
233
|
-
return (<SwiperContext.Provider value={contextValue}>{
|
|
233
|
+
return (<SwiperContext.Provider value={contextValue}>{arrChildren}</SwiperContext.Provider>);
|
|
234
234
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (!props.circular) {
|
|
239
|
-
// 获取下一个位置的坐标, 循环到最后一个元素,直接停止, 取消定时器
|
|
240
|
-
if (currentIndex.value === totalElements.value - 1) {
|
|
241
|
-
pauseLoop();
|
|
235
|
+
const { loop, pauseLoop, resumeLoop } = useMemo(() => {
|
|
236
|
+
function createAutoPlay() {
|
|
237
|
+
if (!step.value)
|
|
242
238
|
return;
|
|
243
|
-
|
|
244
|
-
nextIndex
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
else {
|
|
255
|
-
// 默认向右, 向下
|
|
256
|
-
if (nextIndex === totalElements.value - 1) {
|
|
257
|
-
nextIndex = 0;
|
|
258
|
-
targetOffset = -(totalElements.value + patchElementNum) * step.value + previousMargin;
|
|
259
|
-
// 执行动画到下一帧
|
|
260
|
-
offset.value = withTiming(targetOffset, {
|
|
261
|
-
duration: easeDuration
|
|
262
|
-
}, () => {
|
|
263
|
-
const initOffset = -step.value * patchElementNum + previousMargin;
|
|
264
|
-
// 将开始位置设置为真正的位置
|
|
265
|
-
offset.value = initOffset;
|
|
266
|
-
currentIndex.value = nextIndex;
|
|
267
|
-
runOnJS(loop)();
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
nextIndex = currentIndex.value + 1;
|
|
272
|
-
targetOffset = -(nextIndex + patchElementNum) * step.value + previousMargin;
|
|
273
|
-
// 执行动画到下一帧
|
|
239
|
+
let targetOffset = 0;
|
|
240
|
+
let nextIndex = currentIndex.value;
|
|
241
|
+
if (!circularShared.value) {
|
|
242
|
+
// 获取下一个位置的坐标, 循环到最后一个元素,直接停止, 取消定时器
|
|
243
|
+
if (currentIndex.value === childrenLength.value - 1) {
|
|
244
|
+
pauseLoop();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
nextIndex += 1;
|
|
248
|
+
// targetOffset = -nextIndex * step.value - preMarginShared.value
|
|
249
|
+
targetOffset = -nextIndex * step.value;
|
|
274
250
|
offset.value = withTiming(targetOffset, {
|
|
275
251
|
duration: easeDuration,
|
|
276
252
|
easing: easeMap[easeingFunc]
|
|
@@ -279,297 +255,383 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
279
255
|
runOnJS(loop)();
|
|
280
256
|
});
|
|
281
257
|
}
|
|
258
|
+
else {
|
|
259
|
+
// 默认向右, 向下
|
|
260
|
+
if (nextIndex === childrenLength.value - 1) {
|
|
261
|
+
nextIndex = 0;
|
|
262
|
+
targetOffset = -(childrenLength.value + patchElmNumShared.value) * step.value + preMarginShared.value;
|
|
263
|
+
// 执行动画到下一帧
|
|
264
|
+
offset.value = withTiming(targetOffset, {
|
|
265
|
+
duration: easeDuration
|
|
266
|
+
}, () => {
|
|
267
|
+
const initOffset = -step.value * patchElmNumShared.value + preMarginShared.value;
|
|
268
|
+
// 将开始位置设置为真正的位置
|
|
269
|
+
offset.value = initOffset;
|
|
270
|
+
currentIndex.value = nextIndex;
|
|
271
|
+
runOnJS(loop)();
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
nextIndex = currentIndex.value + 1;
|
|
276
|
+
targetOffset = -(nextIndex + patchElmNumShared.value) * step.value + preMarginShared.value;
|
|
277
|
+
// 执行动画到下一帧
|
|
278
|
+
offset.value = withTiming(targetOffset, {
|
|
279
|
+
duration: easeDuration,
|
|
280
|
+
easing: easeMap[easeingFunc]
|
|
281
|
+
}, () => {
|
|
282
|
+
currentIndex.value = nextIndex;
|
|
283
|
+
runOnJS(loop)();
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
282
287
|
}
|
|
283
|
-
|
|
288
|
+
// loop在JS线程中调用,createAutoPlay + useEffect中
|
|
289
|
+
function loop() {
|
|
290
|
+
timerId.current && clearTimeout(timerId.current);
|
|
291
|
+
timerId.current = setTimeout(createAutoPlay, intervalTimer);
|
|
292
|
+
}
|
|
293
|
+
function pauseLoop() {
|
|
294
|
+
timerId.current && clearTimeout(timerId.current);
|
|
295
|
+
}
|
|
296
|
+
// resumeLoop在worklet中调用
|
|
297
|
+
function resumeLoop() {
|
|
298
|
+
if (autoplayShared.value && childrenLength.value > 1) {
|
|
299
|
+
loop();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
loop,
|
|
304
|
+
pauseLoop,
|
|
305
|
+
resumeLoop
|
|
306
|
+
};
|
|
307
|
+
}, []);
|
|
284
308
|
function handleSwiperChange(current) {
|
|
285
309
|
if (props.current !== currentIndex.value) {
|
|
286
310
|
const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
|
|
287
311
|
props.bindchange && props.bindchange(eventData);
|
|
288
312
|
}
|
|
289
313
|
}
|
|
290
|
-
function getOffset(index) {
|
|
291
|
-
|
|
292
|
-
if (!step.value)
|
|
314
|
+
function getOffset(index, stepValue) {
|
|
315
|
+
if (!stepValue)
|
|
293
316
|
return 0;
|
|
294
317
|
let targetOffset = 0;
|
|
295
|
-
if (
|
|
296
|
-
const targetIndex =
|
|
297
|
-
targetOffset = -(
|
|
318
|
+
if (circular && children.length > 1) {
|
|
319
|
+
const targetIndex = index + patchElmNum;
|
|
320
|
+
targetOffset = -(stepValue * targetIndex - preMargin);
|
|
298
321
|
}
|
|
299
322
|
else {
|
|
300
|
-
targetOffset = -
|
|
323
|
+
targetOffset = -index * stepValue;
|
|
301
324
|
}
|
|
302
325
|
return targetOffset;
|
|
303
326
|
}
|
|
304
|
-
function
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
327
|
+
function updateCurrent(index, stepValue) {
|
|
328
|
+
const targetOffset = getOffset(index || 0, stepValue);
|
|
329
|
+
if (targetOffset !== offset.value) {
|
|
330
|
+
// 内部基于props.current!==currentIndex.value决定是否使用动画及更新currentIndex.value
|
|
331
|
+
if (props.current !== undefined && props.current !== currentIndex.value) {
|
|
332
|
+
offset.value = withTiming(targetOffset, {
|
|
333
|
+
duration: easeDuration,
|
|
334
|
+
easing: easeMap[easeingFunc]
|
|
335
|
+
}, () => {
|
|
336
|
+
currentIndex.value = props.current || 0;
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
offset.value = targetOffset;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
311
343
|
}
|
|
312
|
-
function
|
|
313
|
-
if (
|
|
344
|
+
function updateAutoplay() {
|
|
345
|
+
if (autoplay && children.length > 1) {
|
|
314
346
|
loop();
|
|
315
347
|
}
|
|
348
|
+
else {
|
|
349
|
+
pauseLoop();
|
|
350
|
+
}
|
|
316
351
|
}
|
|
352
|
+
// 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
|
|
317
353
|
useAnimatedReaction(() => currentIndex.value, (newIndex, preIndex) => {
|
|
318
354
|
// 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
|
|
319
|
-
|
|
320
|
-
if (!isInit && newIndex !== preIndex && props.bindchange) {
|
|
355
|
+
if (newIndex !== preIndex && props.bindchange) {
|
|
321
356
|
runOnJS(handleSwiperChange)(newIndex);
|
|
322
357
|
}
|
|
323
358
|
});
|
|
324
359
|
useEffect(() => {
|
|
325
|
-
|
|
326
|
-
|
|
360
|
+
let patchStep = 0;
|
|
361
|
+
if (preMargin !== preMarginShared.value) {
|
|
362
|
+
patchStep += preMargin - preMarginShared.value;
|
|
327
363
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
offset.value = withTiming(targetOffset, {
|
|
331
|
-
duration: easeDuration,
|
|
332
|
-
easing: easeMap[easeingFunc]
|
|
333
|
-
}, () => {
|
|
334
|
-
currentIndex.value = props.current || 0;
|
|
335
|
-
});
|
|
364
|
+
if (nextMargin !== nextMarginShared.value) {
|
|
365
|
+
patchStep += nextMargin - nextMarginShared.value;
|
|
336
366
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
367
|
+
preMarginShared.value = preMargin;
|
|
368
|
+
nextMarginShared.value = nextMargin;
|
|
369
|
+
const newStep = step.value - patchStep;
|
|
370
|
+
if (step.value !== newStep) {
|
|
371
|
+
step.value = newStep;
|
|
372
|
+
offset.value = getOffset(currentIndex.value, newStep);
|
|
341
373
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
374
|
+
}, [preMargin, nextMargin]);
|
|
375
|
+
useEffect(() => {
|
|
376
|
+
childrenLength.value = children.length;
|
|
377
|
+
if (children.length - 1 < currentIndex.value) {
|
|
346
378
|
pauseLoop();
|
|
379
|
+
currentIndex.value = 0;
|
|
380
|
+
offset.value = getOffset(0, step.value);
|
|
381
|
+
if (autoplay && children.length > 1) {
|
|
382
|
+
loop();
|
|
383
|
+
}
|
|
347
384
|
}
|
|
385
|
+
}, [children.length]);
|
|
386
|
+
useEffect(() => {
|
|
387
|
+
updateCurrent(props.current || 0, step.value);
|
|
388
|
+
}, [props.current]);
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
autoplayShared.value = autoplay;
|
|
391
|
+
updateAutoplay();
|
|
348
392
|
return () => {
|
|
349
|
-
if (
|
|
393
|
+
if (autoplay) {
|
|
350
394
|
pauseLoop();
|
|
351
395
|
}
|
|
352
396
|
};
|
|
353
|
-
}, [
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
moveToTargetPos =
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
397
|
+
}, [autoplay]);
|
|
398
|
+
useEffect(() => {
|
|
399
|
+
if (circular !== circularShared.value) {
|
|
400
|
+
circularShared.value = circular;
|
|
401
|
+
patchElmNumShared.value = circular ? (preMargin ? 2 : 1) : 0;
|
|
402
|
+
offset.value = getOffset(currentIndex.value, step.value);
|
|
403
|
+
}
|
|
404
|
+
}, [circular, preMargin]);
|
|
405
|
+
const { gestureHandler } = useMemo(() => {
|
|
406
|
+
function getTargetPosition(eventData) {
|
|
407
|
+
'worklet';
|
|
408
|
+
// 移动的距离
|
|
409
|
+
const { translation } = eventData;
|
|
410
|
+
let resetOffsetPos = 0;
|
|
411
|
+
let selectedIndex = currentIndex.value;
|
|
412
|
+
// 是否临界点
|
|
413
|
+
let isCriticalItem = false;
|
|
414
|
+
// 真实滚动到的偏移量坐标
|
|
415
|
+
let moveToTargetPos = 0;
|
|
416
|
+
const tmp = !circularShared.value ? 0 : preMarginShared.value;
|
|
417
|
+
const currentOffset = translation < 0 ? offset.value - tmp : offset.value + tmp;
|
|
418
|
+
const computedIndex = Math.abs(currentOffset) / step.value;
|
|
419
|
+
const moveToIndex = translation < 0 ? Math.ceil(computedIndex) : Math.floor(computedIndex);
|
|
420
|
+
// 实际应该定位的索引值
|
|
421
|
+
if (!circularShared.value) {
|
|
422
|
+
selectedIndex = moveToIndex;
|
|
423
|
+
moveToTargetPos = selectedIndex * step.value;
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
if (moveToIndex >= childrenLength.value + patchElmNumShared.value) {
|
|
427
|
+
selectedIndex = moveToIndex - (childrenLength.value + patchElmNumShared.value);
|
|
428
|
+
resetOffsetPos = (selectedIndex + patchElmNumShared.value) * step.value - preMarginShared.value;
|
|
429
|
+
moveToTargetPos = moveToIndex * step.value - preMarginShared.value;
|
|
430
|
+
isCriticalItem = true;
|
|
431
|
+
}
|
|
432
|
+
else if (moveToIndex <= patchElmNumShared.value - 1) {
|
|
433
|
+
selectedIndex = moveToIndex === 0 ? childrenLength.value - patchElmNumShared.value : childrenLength.value - 1;
|
|
434
|
+
resetOffsetPos = (selectedIndex + patchElmNumShared.value) * step.value - preMarginShared.value;
|
|
435
|
+
moveToTargetPos = moveToIndex * step.value - preMarginShared.value;
|
|
436
|
+
isCriticalItem = true;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
selectedIndex = moveToIndex - patchElmNumShared.value;
|
|
440
|
+
moveToTargetPos = moveToIndex * step.value - preMarginShared.value;
|
|
441
|
+
}
|
|
379
442
|
}
|
|
380
|
-
|
|
381
|
-
selectedIndex
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
443
|
+
return {
|
|
444
|
+
selectedIndex,
|
|
445
|
+
isCriticalItem,
|
|
446
|
+
resetOffset: -resetOffsetPos,
|
|
447
|
+
targetOffset: -moveToTargetPos
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function canMove(eventData) {
|
|
451
|
+
'worklet';
|
|
452
|
+
const { translation } = eventData;
|
|
453
|
+
const currentOffset = Math.abs(offset.value);
|
|
454
|
+
if (!circularShared.value) {
|
|
455
|
+
if (translation < 0) {
|
|
456
|
+
return currentOffset < step.value * (childrenLength.value - 1);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
return currentOffset > 0;
|
|
460
|
+
}
|
|
385
461
|
}
|
|
386
462
|
else {
|
|
387
|
-
|
|
388
|
-
moveToTargetPos = moveToIndex * step.value - previousMargin;
|
|
463
|
+
return true;
|
|
389
464
|
}
|
|
390
465
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
isCriticalItem,
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
466
|
+
function handleEnd(eventData) {
|
|
467
|
+
'worklet';
|
|
468
|
+
const { isCriticalItem, targetOffset, resetOffset, selectedIndex } = getTargetPosition(eventData);
|
|
469
|
+
if (isCriticalItem) {
|
|
470
|
+
offset.value = withTiming(targetOffset, {
|
|
471
|
+
duration: easeDuration,
|
|
472
|
+
easing: easeMap[easeingFunc]
|
|
473
|
+
}, () => {
|
|
474
|
+
if (touchfinish.value !== false) {
|
|
475
|
+
currentIndex.value = selectedIndex;
|
|
476
|
+
offset.value = resetOffset;
|
|
477
|
+
runOnJS(resumeLoop)();
|
|
478
|
+
}
|
|
479
|
+
});
|
|
405
480
|
}
|
|
406
481
|
else {
|
|
407
|
-
|
|
482
|
+
offset.value = withTiming(targetOffset, {
|
|
483
|
+
duration: easeDuration,
|
|
484
|
+
easing: easeMap[easeingFunc]
|
|
485
|
+
}, () => {
|
|
486
|
+
if (touchfinish.value !== false) {
|
|
487
|
+
currentIndex.value = selectedIndex;
|
|
488
|
+
runOnJS(resumeLoop)();
|
|
489
|
+
}
|
|
490
|
+
});
|
|
408
491
|
}
|
|
409
492
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}, () => {
|
|
422
|
-
if (touchfinish.value !== false) {
|
|
423
|
-
currentIndex.value = selectedIndex;
|
|
424
|
-
offset.value = resetOffset;
|
|
425
|
-
runOnJS(resumeLoop)();
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
493
|
+
function handleBack(eventData) {
|
|
494
|
+
'worklet';
|
|
495
|
+
const { translation } = eventData;
|
|
496
|
+
// 向右滑动的back:trans < 0, 向左滑动的back: trans < 0
|
|
497
|
+
let currentOffset = Math.abs(offset.value);
|
|
498
|
+
if (circularShared.value) {
|
|
499
|
+
currentOffset += translation < 0 ? preMarginShared.value : -preMarginShared.value;
|
|
500
|
+
}
|
|
501
|
+
const curIndex = currentOffset / step.value;
|
|
502
|
+
const moveToIndex = (translation < 0 ? Math.floor(curIndex) : Math.ceil(curIndex)) - patchElmNumShared.value;
|
|
503
|
+
const targetOffset = -(moveToIndex + patchElmNumShared.value) * step.value + (circularShared.value ? preMarginShared.value : 0);
|
|
430
504
|
offset.value = withTiming(targetOffset, {
|
|
431
505
|
duration: easeDuration,
|
|
432
506
|
easing: easeMap[easeingFunc]
|
|
433
507
|
}, () => {
|
|
434
508
|
if (touchfinish.value !== false) {
|
|
435
|
-
currentIndex.value =
|
|
509
|
+
currentIndex.value = moveToIndex;
|
|
436
510
|
runOnJS(resumeLoop)();
|
|
437
511
|
}
|
|
438
512
|
});
|
|
439
513
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
easing: easeMap[easeingFunc]
|
|
452
|
-
}, () => {
|
|
453
|
-
if (touchfinish.value !== false) {
|
|
454
|
-
currentIndex.value = moveToIndex;
|
|
514
|
+
function handleLongPress() {
|
|
515
|
+
'worklet';
|
|
516
|
+
const currentOffset = Math.abs(offset.value);
|
|
517
|
+
let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value;
|
|
518
|
+
if (circularShared.value) {
|
|
519
|
+
preOffset -= preMarginShared.value;
|
|
520
|
+
}
|
|
521
|
+
// 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
|
|
522
|
+
const diffOffset = preOffset - currentOffset;
|
|
523
|
+
const half = Math.abs(diffOffset) > step.value / 2;
|
|
524
|
+
if (+diffOffset === 0) {
|
|
455
525
|
runOnJS(resumeLoop)();
|
|
456
526
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
function handleLongPress(eventData) {
|
|
460
|
-
'worklet';
|
|
461
|
-
const { translation } = eventData;
|
|
462
|
-
const currentOffset = Math.abs(offset.value) + (translation < 0 ? previousMargin : -previousMargin);
|
|
463
|
-
const half = currentOffset % step.value > step.value / 2;
|
|
464
|
-
// 向右trans < 0, 向左trans > 0
|
|
465
|
-
const isExceedHalf = translation < 0 ? half : !half;
|
|
466
|
-
if (+translation === 0) {
|
|
467
|
-
runOnJS(resumeLoop)();
|
|
468
|
-
}
|
|
469
|
-
else if (isExceedHalf) {
|
|
470
|
-
handleEnd(eventData);
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
handleBack(eventData);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
function reachBoundary(eventData) {
|
|
477
|
-
'worklet';
|
|
478
|
-
// 移动的距离
|
|
479
|
-
const { translation } = eventData;
|
|
480
|
-
const elementsLength = step.value * totalElements.value;
|
|
481
|
-
let isBoundary = false;
|
|
482
|
-
let resetOffset = 0;
|
|
483
|
-
// Y轴向下滚动, transDistance > 0, 向上滚动 < 0 X轴向左滚动, transDistance > 0
|
|
484
|
-
const currentOffset = offset.value;
|
|
485
|
-
const moveStep = Math.ceil(translation / elementsLength);
|
|
486
|
-
if (translation < 0) {
|
|
487
|
-
const posEnd = (totalElements.value + patchElementNum + 1) * step.value;
|
|
488
|
-
const posReverseEnd = (patchElementNum - 1) * step.value;
|
|
489
|
-
if (currentOffset < -posEnd + step.value) {
|
|
490
|
-
isBoundary = true;
|
|
491
|
-
resetOffset = Math.abs(moveStep) === 0 ? patchElementNum * step.value + translation : moveStep * elementsLength;
|
|
527
|
+
else if (half) {
|
|
528
|
+
handleEnd({ translation: diffOffset });
|
|
492
529
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
resetOffset = moveStep * elementsLength;
|
|
530
|
+
else {
|
|
531
|
+
handleBack({ translation: diffOffset });
|
|
496
532
|
}
|
|
497
533
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
534
|
+
function reachBoundary(eventData) {
|
|
535
|
+
'worklet';
|
|
536
|
+
// 移动的距离
|
|
537
|
+
const { translation } = eventData;
|
|
538
|
+
const elementsLength = step.value * childrenLength.value;
|
|
539
|
+
let isBoundary = false;
|
|
540
|
+
let resetOffset = 0;
|
|
541
|
+
// Y轴向下滚动, transDistance > 0, 向上滚动 < 0 X轴向左滚动, transDistance > 0
|
|
542
|
+
const currentOffset = offset.value;
|
|
543
|
+
const moveStep = Math.ceil(translation / elementsLength);
|
|
544
|
+
if (translation < 0) {
|
|
545
|
+
const posEnd = (childrenLength.value + patchElmNumShared.value + 1) * step.value;
|
|
546
|
+
const posReverseEnd = (patchElmNumShared.value - 1) * step.value;
|
|
547
|
+
if (currentOffset < -posEnd + step.value) {
|
|
548
|
+
isBoundary = true;
|
|
549
|
+
resetOffset = Math.abs(moveStep) === 0 ? patchElmNumShared.value * step.value + translation : moveStep * elementsLength;
|
|
550
|
+
}
|
|
551
|
+
if (currentOffset > -posReverseEnd) {
|
|
552
|
+
isBoundary = true;
|
|
553
|
+
resetOffset = moveStep * elementsLength;
|
|
554
|
+
}
|
|
504
555
|
}
|
|
505
|
-
if (
|
|
506
|
-
|
|
507
|
-
|
|
556
|
+
else if (translation > 0) {
|
|
557
|
+
const posEnd = (patchElmNumShared.value - 1) * step.value;
|
|
558
|
+
const posReverseEnd = (patchElmNumShared.value + childrenLength.value) * step.value;
|
|
559
|
+
if (currentOffset > -posEnd) {
|
|
560
|
+
isBoundary = true;
|
|
561
|
+
resetOffset = moveStep * elementsLength + step.value + (moveStep === 1 ? translation : 0);
|
|
562
|
+
}
|
|
563
|
+
if (currentOffset < -posReverseEnd) {
|
|
564
|
+
isBoundary = true;
|
|
565
|
+
resetOffset = moveStep * elementsLength + patchElmNumShared.value * step.value;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return {
|
|
569
|
+
isBoundary,
|
|
570
|
+
resetOffset: -resetOffset
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
const gesturePan = Gesture.Pan()
|
|
574
|
+
.onBegin((e) => {
|
|
575
|
+
'worklet';
|
|
576
|
+
if (!step.value)
|
|
577
|
+
return;
|
|
578
|
+
touchfinish.value = false;
|
|
579
|
+
cancelAnimation(offset);
|
|
580
|
+
runOnJS(pauseLoop)();
|
|
581
|
+
preAbsolutePos.value = e[strAbso];
|
|
582
|
+
moveTranstion.value = e[strAbso];
|
|
583
|
+
moveTime.value = new Date().getTime();
|
|
584
|
+
})
|
|
585
|
+
.onTouchesMove((e) => {
|
|
586
|
+
'worklet';
|
|
587
|
+
if (touchfinish.value)
|
|
588
|
+
return;
|
|
589
|
+
const touchEventData = e.changedTouches[0];
|
|
590
|
+
const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
|
|
591
|
+
const eventData = {
|
|
592
|
+
translation: moveDistance
|
|
593
|
+
};
|
|
594
|
+
// 处理用户一直拖拽到临界点的场景, 不会执行onEnd
|
|
595
|
+
if (!circularShared.value && !canMove(eventData)) {
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
const { isBoundary, resetOffset } = reachBoundary(eventData);
|
|
599
|
+
if (isBoundary && circularShared.value) {
|
|
600
|
+
offset.value = resetOffset;
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
offset.value = moveDistance + offset.value;
|
|
604
|
+
}
|
|
605
|
+
preAbsolutePos.value = touchEventData[strAbso];
|
|
606
|
+
})
|
|
607
|
+
.onTouchesUp((e) => {
|
|
608
|
+
'worklet';
|
|
609
|
+
if (touchfinish.value)
|
|
610
|
+
return;
|
|
611
|
+
const touchEventData = e.changedTouches[0];
|
|
612
|
+
const moveDistance = touchEventData[strAbso] - moveTranstion.value;
|
|
613
|
+
touchfinish.value = true;
|
|
614
|
+
const eventData = {
|
|
615
|
+
translation: moveDistance
|
|
616
|
+
};
|
|
617
|
+
// 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
|
|
618
|
+
if (!circularShared.value && !canMove(eventData)) {
|
|
619
|
+
return;
|
|
508
620
|
}
|
|
509
|
-
}
|
|
510
|
-
return {
|
|
511
|
-
isBoundary,
|
|
512
|
-
resetOffset: -resetOffset
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
const gestureHandler = Gesture.Pan()
|
|
516
|
-
.onBegin((e) => {
|
|
517
|
-
'worklet';
|
|
518
|
-
touchfinish.value = false;
|
|
519
|
-
cancelAnimation(offset);
|
|
520
|
-
runOnJS(pauseLoop)();
|
|
521
|
-
preAbsolutePos.value = e[strAbso];
|
|
522
|
-
moveTranstion.value = e[strAbso];
|
|
523
|
-
moveTime.value = new Date().getTime();
|
|
524
|
-
})
|
|
525
|
-
.onTouchesMove((e) => {
|
|
526
|
-
'worklet';
|
|
527
|
-
const touchEventData = e.changedTouches[0];
|
|
528
|
-
const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
|
|
529
|
-
customTrans.value = moveDistance;
|
|
530
|
-
const eventData = {
|
|
531
|
-
translation: moveDistance
|
|
532
|
-
};
|
|
533
|
-
// 处理用户一直拖拽到临界点的场景, 不会执行onEnd
|
|
534
|
-
if (!props.circular && !canMove(eventData)) {
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
const { isBoundary, resetOffset } = reachBoundary(eventData);
|
|
538
|
-
if (isBoundary && props.circular && !touchfinish.value) {
|
|
539
|
-
offset.value = resetOffset;
|
|
540
|
-
}
|
|
541
|
-
else {
|
|
542
|
-
offset.value = moveDistance + offset.value;
|
|
543
|
-
}
|
|
544
|
-
preAbsolutePos.value = touchEventData[strAbso];
|
|
545
|
-
})
|
|
546
|
-
.onTouchesUp((e) => {
|
|
547
|
-
'worklet';
|
|
548
|
-
const touchEventData = e.changedTouches[0];
|
|
549
|
-
const moveDistance = touchEventData[strAbso] - moveTranstion.value;
|
|
550
|
-
touchfinish.value = true;
|
|
551
|
-
const eventData = {
|
|
552
|
-
translation: moveDistance
|
|
553
|
-
};
|
|
554
|
-
// 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
|
|
555
|
-
if (!props.circular && !canMove(eventData)) {
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
if (!moveDistance) {
|
|
559
|
-
handleLongPress({ translation: customTrans.value });
|
|
560
|
-
}
|
|
561
|
-
else {
|
|
562
621
|
const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000;
|
|
563
622
|
if (Math.abs(strVelocity) < longPressRatio) {
|
|
564
|
-
handleLongPress(
|
|
623
|
+
handleLongPress();
|
|
565
624
|
}
|
|
566
625
|
else {
|
|
567
626
|
handleEnd(eventData);
|
|
568
627
|
}
|
|
569
|
-
}
|
|
570
|
-
|
|
628
|
+
});
|
|
629
|
+
return {
|
|
630
|
+
gestureHandler: gesturePan
|
|
631
|
+
};
|
|
632
|
+
}, []);
|
|
571
633
|
const animatedStyles = useAnimatedStyle(() => {
|
|
572
|
-
if (dir
|
|
634
|
+
if (dir === 'x') {
|
|
573
635
|
return { transform: [{ translateX: offset.value }], opacity: step.value > 0 ? 1 : 0 };
|
|
574
636
|
}
|
|
575
637
|
else {
|
|
@@ -577,9 +639,10 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
577
639
|
}
|
|
578
640
|
});
|
|
579
641
|
function renderSwiper() {
|
|
642
|
+
const arrPages = renderItems();
|
|
580
643
|
return (<View style={[normalStyle, layoutStyle, styles.swiper]} {...layoutProps} {...innerProps}>
|
|
581
644
|
<Animated.View style={[{
|
|
582
|
-
flexDirection: dir
|
|
645
|
+
flexDirection: dir === 'x' ? 'row' : 'column',
|
|
583
646
|
width: '100%',
|
|
584
647
|
height: '100%'
|
|
585
648
|
}, animatedStyles]}>
|
|
@@ -595,7 +658,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
595
658
|
{showsPagination && renderPagination()}
|
|
596
659
|
</View>);
|
|
597
660
|
}
|
|
598
|
-
if (
|
|
661
|
+
if (children.length === 1) {
|
|
599
662
|
return renderSwiper();
|
|
600
663
|
}
|
|
601
664
|
else {
|