@gpbagga/react-native-pinch-zoom
v0.1.7
Published
react native library to pinch zoom at a certain point
Maintainers
Readme
react-native-pinch-zoom
A React Native library that provides smooth pinch-to-zoom and pan functionality for any content. Built with React Native Reanimated and Gesture Handler for optimal performance.
Features
- 🔍 Pinch to zoom with smooth animations
- 👆 Pan gesture support when zoomed in
- 🎯 Focal point zooming - zoom at the exact point you pinch
- ⚡ High performance - runs on the UI thread using Reanimated
- 🎛️ Highly customizable - min/max scale, reset behaviors, and more
- 📱 Cross-platform - works on both iOS and Android
- 🎪 Double tap support with configurable reset behavior
Installation
npm install react-native-pinch-zoomPeer Dependencies
This library requires the following peer dependencies:
npm install react-native-gesture-handler react-native-reanimatedMake sure to complete the installation of these libraries by following their respective setup guides:
Important Setup Step
You must wrap your app with GestureHandlerRootView for the gestures to work properly:
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* Your app content */}
</GestureHandlerRootView>
);
}Usage
Basic Example
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { PinchZoomView } from 'react-native-pinch-zoom';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<View style={styles.container}>
<PinchZoomView style={styles.zoomContainer}>
<View style={styles.content}>
<Text style={styles.text}>Pinch me to zoom!</Text>
</View>
</PinchZoomView>
</View>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
zoomContainer: {
width: 300,
height: 300,
backgroundColor: '#f0f0f0',
},
content: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#4CAF50',
},
text: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
});Advanced Example with Images
import React from 'react';
import { View, Image, StyleSheet } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { PinchZoomView } from 'react-native-pinch-zoom';
export default function ImageZoom() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<View style={styles.container}>
<PinchZoomView
minScale={0.5}
maxScale={5}
resetOn={['doubleTap']}
style={styles.imageContainer}
>
<Image
source={{ uri: 'https://picsum.photos/400/600' }}
style={styles.image}
resizeMode="contain"
/>
</PinchZoomView>
</View>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000',
},
imageContainer: {
flex: 1,
},
image: {
width: '100%',
height: '100%',
},
});Conditional Activation Example
import React from 'react';
import { ScrollView, View, Text } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { PinchZoomView } from 'react-native-pinch-zoom';
export default function ConditionalZoom() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<ScrollView>
<PinchZoomView
activateOnlyAfterPinch={true}
resetOn={['releaseIfScaleLessThan1']}
>
<View style={{ padding: 20 }}>
<Text>
This content is in a ScrollView. The zoom will only activate
when you start pinching, allowing normal scrolling otherwise.
</Text>
</View>
</PinchZoomView>
</ScrollView>
</GestureHandlerRootView>
);
}Modal Implementation (Android Specific)
When using PinchZoomView inside a Modal on Android, you need to wrap the Modal content with GestureHandlerRootView for proper gesture handling:
import React from 'react';
import { View, StyleSheet, Image, FlatList, Modal } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { PinchZoomView } from 'react-native-pinch-zoom';
export default function ModalExample() {
return (
<Modal visible={true} transparent={true}>
<GestureHandlerRootView style={{ flex: 1 }}>
<View style={styles.container}>
<FlatList
style={{ width: '100%' }}
data={Array.from({ length: 10 }, (_, index) => index)}
renderItem={({ item }) => (
<PinchZoomView
minScale={1}
resetOn={['doubleTap', 'releaseIfScaleLessThan1']}
>
<Image
source={{
uri: `https://picsum.photos/400/600?random=${item}`,
}}
style={styles.image}
/>
</PinchZoomView>
)}
/>
</View>
</GestureHandlerRootView>
</Modal>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.8)',
},
image: {
width: 300,
height: 200,
marginVertical: 10,
},
});Important Notes for Android Modals:
- Always wrap Modal content with
GestureHandlerRootView - The
GestureHandlerRootViewmay not be the immediate child of the Modal but must be the container of gesture enabled content
API Reference
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | React.ReactNode | Required | The content to be made zoomable |
| minScale | number | 0.25 | Minimum zoom scale |
| maxScale | number | 20 | Maximum zoom scale |
| resetOn | ResetTrigger[] | [] | Array of triggers that reset zoom to original state |
| activateOnlyAfterPinch | boolean | false | If true, pan gestures are disabled until user starts pinching. Recommended when combining with ScrollView, FlatList, or other scrollable components to prevent gesture conflicts. |
Reset Triggers
The resetOn prop accepts an array of the following values:
'release'- Reset when user releases all touches'doubleTap'- Reset when user double taps'releaseIfScaleLessThan1'- Reset only if scale is less than 1 when user releases
Examples of Reset Behaviors
// Reset on double tap (common for image viewers)
<PinchZoomView resetOn={['doubleTap']}>
{/* content */}
</PinchZoomView>
// Reset when user releases if zoomed out
<PinchZoomView resetOn={['releaseIfScaleLessThan1']}>
{/* content */}
</PinchZoomView>
// Reset immediately when user releases (always snap back)
<PinchZoomView resetOn={['release']}>
{/* content */}
</PinchZoomView>
// Multiple reset triggers
<PinchZoomView resetOn={['doubleTap', 'releaseIfScaleLessThan1']}>
{/* content */}
</PinchZoomView>Use Cases
- Image galleries - Allow users to zoom into photos
- Maps and diagrams - Enable detailed inspection of complex visuals
- Documents and PDFs - Improve readability of text content
- Charts and graphs - Allow users to examine data points closely
- Art and design apps - Provide detailed view of creative work
Performance Notes
This library is built on top of React Native Reanimated and Gesture Handler, which means:
- ✅ Animations run on the UI thread (60fps)
- ✅ Gestures are handled natively
- ✅ No bridge communication during interactions
- ✅ Smooth performance even on lower-end devices
Contributing
License
MIT
Made with create-react-native-library
