expo-dynamic-image-crop
Version:
Dynamic image cropping component for Expo/React Native with free-form and fixed aspect ratio support
213 lines (146 loc) ⢠7.25 kB
Markdown
# Expo Dynamic Image Crop
A powerful and flexible image cropping component for Expo/React Native applications with dynamic cropping capabilities, fixed aspect ratios, and smooth gesture handling.
## š± **Live Demo**
<div align="center">
<img src="https://raw.githubusercontent.com/nwabueze1/expo-dynamic-image-crop/main/docs/images/crop-demo.png" alt="Corner Dragging Demo" width="300" />
</div>
_All four corner markers work perfectly - drag from any corner for smooth, real-time cropping!_
## ⨠Features
- š¼ļø **Dynamic Cropping**: Free-form cropping with independent width/height adjustment
- š **Fixed Aspect Ratios**: Support for common ratios (1:1, 16:9, 4:3, etc.)
- š **Gesture Support**: Smooth pinch-to-zoom and pan gestures
- šØ **Customizable UI**: Beautiful, modern interface with customizable controls
- š± **Expo Ready**: Optimized for Expo managed workflow
- š§ **TypeScript**: Full TypeScript support with proper type definitions
- š **Self-Contained**: No external state management required - works out of the box
- š **Cross-Platform**: Works identically on both Android and iOS - write once, run everywhere
- š **Easily Discoverable**: Top search results for "expo image crop", "react native image editor", and "dynamic crop"
- ā” **React 19+ Compatible**: Uses Zustand for state management, no provider or setup required
> **Note:** This package now uses [Zustand](https://github.com/pmndrs/zustand) for state management. No need to wrap your app in any provider. Fully compatible with React 19+ and Expo managed workflow.
## š Installation
**Simple one-command installation:**
```bash
npx expo install expo-dynamic-image-crop
```
That's it! All dependencies are included. ā
### Manual Installation (if needed):
```bash
npm install expo-dynamic-image-crop
# Only install these if you don't already have them:
npx expo install expo-image-manipulator react-native-gesture-handler
```
## š¦ Dependencies Explained
We use a **hybrid approach** for optimal user experience:
- **Included**: `@expo/vector-icons`, `expo-image-manipulator`, `react-native-gesture-handler`, `zustand`
- **Peer Dependencies**: `expo`, `react`, `react-native` (you already have these in Expo projects)
This means **zero extra installation steps** for most users! š
## š Cross-Platform Compatibility
**Perfect Android & iOS Support:**
- ā
**Identical Behavior**: Same gestures, UI, and functionality on both platforms
- ā
**Native Performance**: Leverages platform-specific optimizations under the hood
- ā
**Consistent Design**: Looks and feels native on both Android and iOS
- ā
**No Platform-Specific Code**: One component works everywhere
**Tested on:**
- š± iOS 14+ (iPhone & iPad)
- š¤ Android API 21+ (Phone & Tablet)
- š Expo SDK 49+
## š Quick Start
**Use the ImageEditor component directly - no setup required:**
```tsx
import React, { useState } from "react";
import { View, Image, Button } from "react-native";
import { ImageEditor } from "expo-dynamic-image-crop";
export default function MyScreen() {
const [imageUri, setImageUri] = useState<string | null>(null);
const [isEditing, setIsEditing] = useState(false);
const handleCropComplete = (croppedImageData: any) => {
setImageUri(croppedImageData.uri);
setIsEditing(false);
};
return (
<View style={{ flex: 1 }}>
{imageUri && (
<Image source={{ uri: imageUri }} style={{ width: 200, height: 200 }} />
)}
<Button title="Edit Image" onPress={() => setIsEditing(true)} />
<ImageEditor
isVisible={isEditing}
imageUri="your-image-uri-here"
onEditingComplete={handleCropComplete}
onEditingCancel={() => setIsEditing(false)}
fixedAspectRatio={1} // Optional: 1 for square, undefined for free-form
dynamicCrop={true} // Enable dynamic cropping
/>
</View>
);
}
```
## š§āš» Example App
Want to see this package in action?
Check out the full example Expo app here:
š [expo-dynamic-image-crop-example (GitHub)](https://github.com/nwabueze1/expo-dynamic-image-crop-example)
- The **Index screen** demonstrates dynamic cropping (free-form).
- The **Explore screen** demonstrates fixed aspect ratio cropping.
Clone, run, and experiment with all features before integrating into your own project!
## šļø Cropping Modes
### Free-Form Cropping (Dynamic)
```tsx
<ImageEditor
isVisible={isEditing}
imageUri={imageUri}
onEditingComplete={handleCrop}
onEditingCancel={handleClose}
dynamicCrop={true} // Free-form cropping
/>
```
### Fixed Aspect Ratios
```tsx
// Square (1:1)
<ImageEditor isVisible={isEditing} fixedAspectRatio={1} dynamicCrop={false} />
// Landscape (16:9)
<ImageEditor isVisible={isEditing} fixedAspectRatio={16/9} dynamicCrop={false} />
// Portrait (4:3)
<ImageEditor isVisible={isEditing} fixedAspectRatio={3/4} dynamicCrop={false} />
```
## šÆ **Visual Showcase**
<div align="center">
<img src="https://raw.githubusercontent.com/nwabueze1/expo-dynamic-image-crop/main/docs/images/crop-demo.png" alt="Professional Corner Dragging" width="400" />
**⨠Professional-Grade Corner Dragging**
- All 4 corners work smoothly
- Real-time visual feedback
- Perfect for production apps
</div>
## š API Reference
### ImageEditor Props
| Prop | Type | Default | Description |
| ------------------- | --------------------------- | ------------ | ---------------------------------- |
| `isVisible` | `boolean` | **Required** | Controls modal visibility |
| `imageUri` | `string` | **Required** | URI of the image to crop |
| `onEditingComplete` | `(data: ImageData) => void` | **Required** | Callback when cropping is complete |
| `onEditingCancel` | `() => void` | **Required** | Callback when editing is cancelled |
| `fixedAspectRatio` | `number \| undefined` | `undefined` | Fixed aspect ratio (width/height) |
| `dynamicCrop` | `boolean` | `true` | Enable free-form cropping |
| `quality` | `number` | `1.0` | Output image quality (0-1) |
## šØ Customization
The component comes with a beautiful default UI, but you can customize it by modifying the components in your node_modules or by creating your own wrapper.
## š Why Choose This Package?
**Top Search Results for:**
- š„ "expo image crop"
- š„ "react native image editor"
- š„ "dynamic crop react native"
- š„ "expo image cropping component"
**Best-in-Class Features:**
- Zero setup required (self-contained)
- Perfect cross-platform compatibility
- Modern TypeScript support
- Active maintenance and updates
- Comprehensive documentation
- **React 19+ compatible** (thanks to Zustand!)
## š¤ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## š License
MIT License - feel free to use in personal and commercial projects.
## š Issues & Support
If you encounter any issues or need support, please create an issue on GitHub.
---
**Made with ā¤ļø for the Expo community**