UNPKG

react-native-momentum-carousel

Version:

A React Native carousel component enables smooth and interactive image or content sliders with swiping capabilities. Ideal for showcasing multiple items or images in a compact space, this carousel can be customized with features like infinite scrolling, p

158 lines (149 loc) 7.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useLayoutDefaultAnimation = useLayoutDefaultAnimation; exports.useLayoutStackAnimation = useLayoutStackAnimation; exports.useLayoutTinderAnimation = useLayoutTinderAnimation; var _react = require("react"); var _reactNativeReanimated = require("react-native-reanimated"); /** * useLayoutStackAnimation calculates the animated style for a stack-style carousel animation. * It creates an opacity and scaling effect for each carousel item based on the scroll position (scrollX). * The items will scale down when not in the center and will move slightly to the left or right as they approach the center. */ function useLayoutStackAnimation(data) { // Calculate the input range based on the current index and direction (vertical/horizontal) const inputRange = (0, _react.useMemo)(() => { const currentIndex = data.info.index; return [(currentIndex - 1) * (!data.vertical ? data.itemWidth : data.itemHeight), // previous item position currentIndex * (!data.vertical ? data.itemWidth : data.itemHeight), // current item position (currentIndex + 1) * (!data.vertical ? data.itemWidth : data.itemHeight) // next item position ]; }, [data.info.index, data.itemHeight, data.itemWidth, data.vertical]); // Animated style that adjusts opacity, scale, and translation based on scroll position const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { return { opacity: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, // The scroll position value used to interpolate inputRange, [0.8, 1, 0.8], // Decrease opacity when items are not in the center _reactNativeReanimated.Extrapolation.CLAMP // Prevent extrapolation beyond the defined range ), transform: [{ scale: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [data.inactiveScale ? data.inactiveScale : 0.8, // Scale down inactive items 1, // Scale to 1 when the item is centered data.inactiveScale ? data.inactiveScale : 0.8 // Scale back down when the item is out of focus ], _reactNativeReanimated.Extrapolation.CLAMP) }, // Apply horizontal or vertical translation depending on the orientation !data.vertical ? { translateX: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [200, 0, 200], // Move items to the sides when not centered _reactNativeReanimated.Extrapolation.CLAMP) } : { translateY: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [200, 0, 200], // Move items vertically when not centered _reactNativeReanimated.Extrapolation.CLAMP) }] }; }, [data.scrollX, inputRange]); // Return the animated style that will be applied to each item return animatedStyle; } /** * useLayoutDefaultAnimation creates a default animation for carousel items. * It interpolates opacity and scaling based on the scroll position (scrollX). * The default animation scales the items and adjusts their opacity when scrolling. */ function useLayoutDefaultAnimation(data) { // Calculate the input range based on the current index and direction (vertical/horizontal) const inputRange = (0, _react.useMemo)(() => { const currentIndex = data.info.index; return [(currentIndex - 1) * (!data.vertical ? data.itemWidth : data.itemHeight), // previous item position currentIndex * (!data.vertical ? data.itemWidth : data.itemHeight), // current item position (currentIndex + 1) * (!data.vertical ? data.itemWidth : data.itemHeight) // next item position ]; }, [data.info.index, data.itemHeight, data.itemWidth, data.vertical]); // Animated style that adjusts opacity and scale for the default animation const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { return { opacity: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, // The scroll position value used to interpolate inputRange, [0.8, 1, 0.8], // Decrease opacity when items are not in the center _reactNativeReanimated.Extrapolation.CLAMP // Prevent extrapolation beyond the defined range ), transform: [{ scale: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [data.inactiveScale ? data.inactiveScale : 0.8, // Scale down inactive items 1, // Scale to 1 when the item is centered data.inactiveScale ? data.inactiveScale : 0.8 // Scale back down when the item is out of focus ], _reactNativeReanimated.Extrapolation.CLAMP) }] }; }, [data.scrollX, inputRange]); // Return the default animated style return animatedStyle; } /** * useLayoutTinderAnimation creates a Tinder-style animation for carousel items. * It includes a combination of opacity, scale, translation (X and Y), and rotation based on the scroll position (scrollX). * This creates a dynamic "card-stack" effect with items rotating and translating as they approach or leave the center. */ function useLayoutTinderAnimation(data) { // Calculate the input range based on the current index and direction (vertical/horizontal) const inputRange = (0, _react.useMemo)(() => { const currentIndex = data.info.index; return [(currentIndex - 1) * (!data.vertical ? data.itemWidth : data.itemHeight), // previous item position currentIndex * (!data.vertical ? data.itemWidth : data.itemHeight), // current item position (currentIndex + 1) * (!data.vertical ? data.itemWidth : data.itemHeight) // next item position ]; }, [data.info.index, data.itemHeight, data.itemWidth, data.vertical]); // Animated style that applies opacity, scale, translation, and rotation for the Tinder-like animation const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { return { opacity: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, // The scroll position value used to interpolate inputRange, [0.8, 1, 0.8], // Decrease opacity when items are not in the center _reactNativeReanimated.Extrapolation.CLAMP // Prevent extrapolation beyond the defined range ), transform: [{ scale: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [data.inactiveScale ? data.inactiveScale : 0.8, // Scale down inactive items 1, // Scale to 1 when the item is centered data.inactiveScale ? data.inactiveScale : 0.8 // Scale back down when the item is out of focus ], _reactNativeReanimated.Extrapolation.CLAMP) }, { // Horizontal translation for Tinder-style effect translateX: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [100, 0, 100], // Move the item horizontally for the "stack" effect _reactNativeReanimated.Extrapolation.CLAMP) }, { // Vertical translation for Tinder-style effect translateY: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [30, 0, 0], // Move the item vertically for the "stack" effect _reactNativeReanimated.Extrapolation.CLAMP) }, { // Rotation for Tinder-style effect rotate: (0, _reactNativeReanimated.interpolate)(data.scrollX.value, inputRange, [22, 0, 0], // Rotate the item as it leaves the center _reactNativeReanimated.Extrapolation.CLAMP) + 'deg' // Apply the degree of rotation }] }; }, [data.scrollX, inputRange]); // Return the animated style that creates the Tinder effect return animatedStyle; } //# sourceMappingURL=useLayoutAnimation.js.map