diff --git a/src/hooks/useOffsetX.ts b/src/hooks/useOffsetX.ts index 333a5dcb..9442b1a9 100644 --- a/src/hooks/useOffsetX.ts +++ b/src/hooks/useOffsetX.ts @@ -25,11 +25,23 @@ export const useOffsetX = (opts: IOpts, visibleRanges: IVisibleRanges) => { type = 'positive', viewCount = Math.round((data.length - 1) / 2), } = opts; + const ITEM_LENGTH = data.length; const VALID_LENGTH = ITEM_LENGTH - 1; const TOTAL_WIDTH = size * ITEM_LENGTH; const HALF_WIDTH = 0.5 * size; + const positiveCount = + type === 'positive' ? viewCount : VALID_LENGTH - viewCount; + + let startPos = size * index; + if (index > positiveCount) { + startPos = (index - ITEM_LENGTH) * size; + } + + const MAX = positiveCount * size; + const MIN = -((VALID_LENGTH - positiveCount) * size); + const x = useDerivedValue(() => { const { negativeRange, positiveRange } = visibleRanges.value; if ( @@ -38,18 +50,8 @@ export const useOffsetX = (opts: IOpts, visibleRanges: IVisibleRanges) => { ) { return Number.MAX_SAFE_INTEGER; } - if (loop) { - const positiveCount = - type === 'positive' ? viewCount : VALID_LENGTH - viewCount; - - let startPos = size * index; - if (index > positiveCount) { - startPos = (index - ITEM_LENGTH) * size; - } - - const MAX = positiveCount * size; - const MIN = -((VALID_LENGTH - positiveCount) * size); + if (loop) { const inputRange = [ -TOTAL_WIDTH, MIN - HALF_WIDTH - startPos - Number.MIN_VALUE, diff --git a/src/layouts/StackLayout.tsx b/src/layouts/StackLayout.tsx index 0804f53a..8c6b909a 100644 --- a/src/layouts/StackLayout.tsx +++ b/src/layouts/StackLayout.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Dimensions, StyleSheet } from 'react-native'; import Animated, { + Extrapolate, interpolate, runOnJS, useAnimatedReaction, @@ -53,51 +54,47 @@ export const StackLayout: React.FC<{ ); const offsetXStyle = useAnimatedStyle(() => { - const startPosition = (x.value - index * size) / size; + const value = x.value / size; + const showLength = 3; + const validLength = showLength - 1; return { transform: [ { translateX: interpolate( - startPosition, - [-(index + 1), -index, 0], - [-(PAGE_WIDTH - size) * 2, 0, 0] + value, + [-1, 0, validLength], + [-PAGE_WIDTH, 0, 0], + Extrapolate.CLAMP ), }, { scale: interpolate( - startPosition, - [-index - 1, -index, 0, data.length - index], - [ - 1, - 1, - 1 - index * 0.09, - 1 - (data.length - index) * 0.09, - ] + value, + [0, validLength], + [1, 1 - validLength * 0.08], + Extrapolate.CLAMP ), }, { rotateZ: `${interpolate( - startPosition, - [-index - 1, -index, 0], - [-135, 0, 0] + value, + [-1, 0], + [-135, 0], + Extrapolate.CLAMP )}deg`, }, { translateY: interpolate( - startPosition, - [-index - 1, -index, 0, data.length - index], - [ - 0, - 0, - index * size * 0.12, - (data.length - index) * size * 0.12, - ] + value, + [0, validLength], + [0, validLength * 30], + Extrapolate.CLAMP ), }, ], zIndex: -interpolate( - startPosition, + (x.value - index * size) / size, [-index - 1, -index - 0.5, -index, 0, data.length - index], [ Number.MAX_VALUE,