Skip to content

Commit

Permalink
Merge pull request #1711 from didi/feat-swiper-refactor
Browse files Browse the repository at this point in the history
Swiper重构
  • Loading branch information
hiyuki authored Jan 15, 2025
2 parents 6fe4f86 + ba66a74 commit b440816
Show file tree
Hide file tree
Showing 6 changed files with 789 additions and 705 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const IntersectionObserverContext = createContext<IntersectionObserver |

export const RouteContext = createContext<number | null>(null)

export const SwiperContext = createContext({})

export const KeyboardAvoidContext = createContext<KeyboardAvoidContextValue | null>(null)

export const ScrollViewContext = createContext<ScrollViewContextValue>({ gestureRef: null })
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { View, LayoutChangeEvent } from 'react-native'
import { ReactNode, forwardRef, useRef } from 'react'
import { View } from 'react-native'
import Animated, { useAnimatedStyle, interpolate, SharedValue } from 'react-native-reanimated'
import { ReactNode, forwardRef, useRef, useContext } from 'react'
import useInnerProps from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils'
import { SwiperContext } from './context'

interface SwiperItemProps {
'item-id'?: string;
Expand All @@ -14,15 +16,31 @@ interface SwiperItemProps {
'parent-height'?: number;
children?: ReactNode;
style?: Object;
customStyle: Object;
itemIndex: number;
}

interface ContextType {
offset: SharedValue<number>;
step: SharedValue<number>;
scale: boolean;
dir: string;
}

const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProps>((props: SwiperItemProps, ref) => {
const {
'enable-var': enableVar,
'external-var-context': externalVarContext,
style
style,
customStyle,
itemIndex
} = props

const contextValue = useContext(SwiperContext) as ContextType
const offset = contextValue.offset || 0
const step = contextValue.step || 0
const scale = contextValue.scale || false
const dir = contextValue.dir || 'x'
const { textProps } = splitProps(props)
const nodeRef = useRef(null)

Expand All @@ -47,19 +65,35 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
} = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: nodeRef })

const innerProps = useInnerProps(props, {
style: { ...innerStyle, ...layoutStyle },
ref: nodeRef,
...layoutProps
}, [
'children',
'enable-offset'
'enable-offset',
'style'
], { layoutRef })

const itemAnimatedStyle = useAnimatedStyle(() => {
if (!step.value) return {}
const inputRange = [step.value, 0]
const outputRange = [0.7, 1]
// 实现元素的宽度跟随step从0到真实宽度,且不能触发重新渲染整个组件,通过AnimatedStyle的方式实现
const outerLayoutStyle = dir === 'x' ? { width: step.value, height: '100%' } : { width: '100%', height: step.value }
const transformStyle = []
if (scale) {
transformStyle.push({
scale: interpolate(Math.abs(Math.abs(offset.value) - itemIndex * step.value), inputRange, outputRange)
})
}
return Object.assign(outerLayoutStyle, {
transform: transformStyle
})
})
return (
<View
data-itemId={props['item-id']}
{...innerProps}>
{
<Animated.View
{...innerProps}
style={[innerStyle, layoutStyle, itemAnimatedStyle, customStyle]}
data-itemId={props['item-id']}>
{
wrapChildren(
props,
{
Expand All @@ -70,7 +104,7 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
}
)
}
</View>
</Animated.View>
)
})

Expand Down
Loading

0 comments on commit b440816

Please sign in to comment.