Closed dohooo closed 2 years ago
Stellar work on this library. Wondering if a combination of vertical and horizontal mode is possible.
Thank you. It seems that it is not possible at present. More modifications are needed.
Hey @dohooo, I've been looking at your multiple example again, and I've been hitting an issue which I would call "overscrolling".
When the carousel is set to "loop", everything works as expected, however when loop is disabled, you can scroll the last element all the way to "position 1" instead of it being the last item in the carousel.
Current Implementation: | Slot 1 | Slot 2 | Slot 3 |
---|---|---|---|
LastItem | Empty | Empty |
Ideal Implementation | Slot 1 | Slot 2 | Slot 3 |
---|---|---|---|
ThirdLastItem | SecondLastItem | LastItem |
I've attached a minimal reproduction in expo here: https://snack.expo.dev/@srobbins/reanimated-carousel-overscroll-example
I think this would be made possible by allowing us to set maxPages on the ScrollViewGesture, where maxPages would be totalItems.length - numberOfItemsOnScreen
, however there would still be a slight problem of navigating to the last item.
Curious what you think about this!
Edit: I believe this is the same issue as #240.
@dohooo I have a PR that adds support for this here: https://github.com/dohooo/react-native-reanimated-carousel/pull/295
@dohooo I have a PR that adds support for this here: #295
Solved in #297.
hey @dohooo , how can do style like this ? is it possible without parallax ?
stacked card animations that look like this would be amazing:
One other request: "Auto Height" for horizontal layouts. I know this might not be possible, as the items are currently all positioned absolutely, but it would be great to be able to size to height of the carousel based on the height of the contents. This was achievable in snap-carousel, but they may have been using a very different strategy.
Has someone already found a way for this? Or is it just not possible?
How to use parallax mode, but hide the left nad right item. so the active item will show full width screen ?
Which layout should I use to achieve something like this?
Hi! I managed to dynamically retrieve the height of the carousel items. While it requires a bit more effort, it is possible as shown below:
How It Works: 1) Measure Item Heights: Each item is rendered invisibly off-screen to capture its height using the measure function. 2) Set Initial Height: The maximum height of all items is set as the initial height of the carousel. 3) Update on Scroll: As the carousel scrolls, the height is dynamically updated based on the height of the currently visible item.
const Advertising = () => {
const items = []; // TODO
const carouselRef = React.useRef<ICarouselInstance>(null);
const [activeSlide, setActiveSlide] = useState(0);
const {width: screenWidth} = useWindowDimensions();
const [itemHeights, setItemHeights] = useState([]);
const [carouselHeight, setCarouselHeight] = useState(0);
const itemRefs = useRef([]);
useEffect(() => {
const heights = items.map((item, index) => {
return new Promise(resolve => {
itemRefs.current[index]?.measure((x, y, width, height) => {
resolve(height);
});
});
});
Promise.all(heights).then(heights => {
setItemHeights(heights);
setCarouselHeight(Math.max(...heights)); // Set the initial height to the maximum item height
});
}, [items]);
const handleScrollEnd = (index: number) => {
setCarouselHeight(itemHeights[index]);
setActiveSlide(index);
};
const renderItem = ({
item,
index,
renderHidden,
}: {
item: AdsProps;
index: number;
renderHidden: boolean;
}) => {
return (
<View
key={item.cd_matia}
style={[
styles.listItem,
renderHidden && {opacity: 0, zIndex: -1, position: 'absolute'},
!renderHidden && {height: itemHeights[index]},
]}
ref={ref => renderHidden && (itemRefs.current[index] = ref)}>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => openNewsDetails(item.ds_matia_link)}>
<CustomImage url={item.imagem} width={120} height={96} />
</TouchableOpacity>
<View style={styles.textContainer}>
<NewsItemSubject subject={item.ds_matia_assun} />
<TouchableOpacity onPress={() => openNewsDetails(item.ds_matia_link)}>
<TextPrimary style={styles.listItemTitle}>
{item.ds_matia_titulo}
</TextPrimary>
</TouchableOpacity>
</View>
</View>
);
};
const moveAnimation = useRef(new Animated.Value(0)).current;
const moveOffset = 90;
useEffect(() => {
const toValue = -((moveOffset / items.length) * activeSlide);
if (!isNaN(toValue)) {
Animated.timing(moveAnimation, {
toValue: toValue,
duration: 1000,
useNativeDriver: true,
easing: Easing.out(Easing.cubic),
}).start();
}
}, [moveAnimation, activeSlide]);
return (
<View style={styles.container}>
<View style={styles.rowContainer}>
{items &&
items.map((item, index) =>
renderItem({item, index, renderHidden: true}),
)}
{/* {items &&
items.map((item, index) => (
<View
key={`measure-${index}`}
ref={ref => (itemRefs.current[index] = ref)}
style={[
styles.listItem,
{opacity: 0, zIndex: 2, position: 'absolute'},
]}>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => openNewsDetails(item.ds_matia_link)}>
<CustomImage url={item.imagem} width={120} height={96} />
</TouchableOpacity>
<View style={styles.textContainer}>
<NewsItemSubject subject={item.ds_matia_assun} />
<TouchableOpacity
onPress={() => openNewsDetails(item.ds_matia_link)}>
<TextPrimary style={styles.listItemTitle}>
{item.ds_matia_titulo}
</TextPrimary>
</TouchableOpacity>
</View>
</View>
))} */}
<Carousel
ref={carouselRef}
data={items}
width={screenWidth}
height={carouselHeight || 50}
loop={true}
renderItem={({item, index}) =>
renderItem({item, index, render: false})
}
onScrollEnd={handleScrollEnd}
pagingEnabled={true}
style={{width: '100%'}}
/>
</View>
</View>
);
Writing here!
BTW, looking forward to your PR!~ 🍺