English | ํ๊ตญ์ด
Have you ever struggled with implementing complex gesture handling and animations when building image galleries or content viewers in React Native?
Existing libraries often have limited customization options or performance issues. react-native-gesture-image-viewer
is a high-performance universal gesture viewer library built on React Native Reanimated and Gesture Handler, providing complete customization and intuitive gesture support for not only images but also videos, custom components, and any other content.
- ๐ค Complete Gesture Support - Pinch zoom, double-tap zoom, swipe navigation, pan when zoomed-in, and vertical drag to dismiss
- ๐๏ธ High-Performance Animations - Smooth and responsive animations at 60fps and beyond, powered by React Native Reanimated
- ๐จ Full Customization - Total control over components, styles, and gesture behavior
- ๐๏ธ External Control API - Trigger actions programmatically from buttons or other UI components
- ๐งฉ Multi-Instance Management - Manage multiple viewers independently using unique IDs
- ๐งฌ Flexible Integration - Use with Modal, React Native Modal, ScrollView, FlatList, FlashList, Expo Image, FastImage, and more
- ๐ง Full TypeScript Support - Great developer experience with type inference and safety
- ๐ Cross-Platform - Runs on iOS, Android, and Web with Expo Go and New Architecture compatibility
- ๐ช Easy-to-Use API - Simple and intuitive API that requires minimal setup
Full documentation is available at: https://react-native-gesture-image-viewer.pages.dev
- ๐ Example Project - Real implementation code with various use cases
- ๐ค Expo Go - Try it instantly on Snack Expo
react-native-gesture-image-viewer
is a library focused purely on gesture interactions for complete customization.
import { useCallback, useState } from 'react';
import { ScrollView, Image, Modal, View, Text, Button } from 'react-native';
import { GestureViewer, useGestureViewerController, useGestureViewerEvent } from 'react-native-gesture-image-viewer';
function App() {
const images = [...];
const [visible, setVisible] = useState(false);
const { goToIndex, goToPrevious, goToNext, currentIndex, totalCount } = useGestureViewerController();
const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
}, []);
useGestureViewerEvent('zoomChange', (data) => {
console.log(`Zoom changed from ${data.previousScale} to ${data.scale}`);
});
return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={ScrollView}
onDismiss={() => setVisible(false)}
/>
<View>
<Button title="<" onPress={goToPrevious} />
<Button title="Jump to index 2" onPress={() => goToIndex(2)} />
<Button title=">" onPress={goToNext} />
<Text>{`${currentIndex + 1} / ${totalCount}`}</Text>
</View>
</Modal>
);
}
For details on how to contribute to the project and set up the development environment, please refer to the Contributing Guide.