Skip to content
61 changes: 41 additions & 20 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-swiper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -604,28 +604,20 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
function handleEnd (eventData: EventDataType) {
'worklet'
const { isCriticalItem, targetOffset, resetOffset, selectedIndex } = getTargetPosition(eventData)
if (isCriticalItem) {
offset.value = withTiming(targetOffset, {
duration: easeDuration,
easing: easeMap[easeingFunc]
}, () => {
if (touchfinish.value !== false) {
currentIndex.value = selectedIndex

offset.value = withTiming(targetOffset, {
duration: easeDuration,
easing: easeMap[easeingFunc]
}, () => {
if (touchfinish.value !== false) {
currentIndex.value = selectedIndex
// 只在临界情况下设置 resetOffset
if (isCriticalItem) {
offset.value = resetOffset
runOnJS(runOnJSCallback)('resumeLoop')
}
})
} else {
offset.value = withTiming(targetOffset, {
duration: easeDuration,
easing: easeMap[easeingFunc]
}, () => {
if (touchfinish.value !== false) {
currentIndex.value = selectedIndex
runOnJS(runOnJSCallback)('resumeLoop')
}
})
}
runOnJS(runOnJSCallback)('resumeLoop')
}
})
}
function handleBack (eventData: EventDataType) {
'worklet'
Expand All @@ -648,6 +640,32 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
}
})
}
function handleInertialSlide (eventData: EventDataType, velocity: number) {
'worklet'
const clampedVelocity = Math.min(Math.abs(velocity), 900)
const { isCriticalItem, targetOffset, resetOffset, selectedIndex } = getTargetPosition(eventData)

// 基于速度计算动画持续时间
const velocityFactor = Math.min(clampedVelocity / 1000, 1.2)
const baseDuration = 300
const minDuration = 250
const duration = Math.max(baseDuration / velocityFactor, minDuration)
// 合并重复的动画逻辑
offset.value = withTiming(targetOffset, {
duration: duration,
easing: Easing.bezier(0.25, 0.1, 0.25, 1)
}, (finished) => {
'worklet'
if (finished) {
currentIndex.value = selectedIndex
// 只在临界情况下设置 resetOffset
if (isCriticalItem) {
offset.value = resetOffset
}
runOnJS(runOnJSCallback)('resumeLoop')
}
})
}
// 当前的offset和index多对应的offset进行对比,判断是否超过一半
function computeHalf (eventData: EventDataType) {
'worklet'
Expand Down Expand Up @@ -823,6 +841,9 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
const velocity = e[strVelocity]
if (Math.abs(velocity) < longPressRatio) {
handleLongPress(eventData)
} else if (Math.abs(velocity) > 200) {
// 速度较大,使用惯性滑动
handleInertialSlide(eventData, velocity)
} else {
handleEnd(eventData)
}
Expand Down