Important!
The library uses Reanimated 2 alpha. It means that it may be unstable. Also, the library itself is in the alpha testing stage and may contain bugs.
Use npm or yarn to install the library
npm i --save react-native-gallery-toolkit
Also, you need to install [email protected] (then new 2 version) and react-native-gesture-handler, and follow their installation instructions.
Expo is not currently supported because it doesn't support Reanimated 2.
Important!
There is a bug in [email protected] that causes gesture event handlers to reattach on each render. You can apply this patch to workaround it.
Standalone gallery renders Pager which supports thousands of images thanks to virtualization. Each page renders ImageTransformer component which gives ability to pinch-to-zoom, double tap to zoom, also you can run custom callbacks and worklets on on tab, double tap, pan.
import {
StandaloneGallery,
GalleryItemType,
StandaloneGalleryHandler,
} from 'react-native-gallery-toolkit';
const images: GalleryItemType[] = [
{
id: '1',
width: 300,
height: 300,
uri: 'https://placekitten.com/300/300',
},
{
id: '2',
width: 400,
height: 200,
uri: 'https://placekitten.com/400/200',
},
];
export default function App() {
return <StandaloneGallery items={images} />;
}
See Full featured example for example of usage of all the props.
- Only portrait orientation currently supported
- There is no way to change dimensions without full re-render of the gallery
- Debugging is not supported because of Reanimated v2 uses TurboModules. Use flipper to debug your JS Context.
- On Android tap on hold on the screen while page changes doesn't trigger animation to stop due to bug in Gesture Handler.
Prop | Description | Type | Default |
---|---|---|---|
items |
The array of items to render. But can also accept Map, Set, or Object with keys. If the type is not array, then getTotalCount and getItem should be defined too. |
Array<{ width: number, height: number, id: string, uri: string }> |
undefined |
width? |
Viewport width | number |
Dimensions.get('window').width |
height? |
Viewport height | number |
Dimensions.get('window').height |
numToRender? |
How many pages should be rendered at the same time | number |
2 |
gutterWidth? |
The width of the gutter between pages | number |
0 |
initialIndex? |
The initial page index | number |
0 |
keyExtractor? |
Callback which extract the key of the page. Receives current item of the provided items as well as current index |
(item: T, index: number) => string |
Uses index as a key by default |
Prop | Description | Type | Default |
---|---|---|---|
getTotalCount? |
If the type of items is not an array, then this method should be defined to provide the total count of items |
(data: T) => number |
Required when items is not an array |
getItem? |
If the type of items is not an array, then this method should be defined to provide the current item based on the index. Can return either the item or undefined . |
(data: T, index: number) => ItemT or undefined |
Required when items is not an array |
renderImage? |
Callback that can be used to render custom image component. As an example, it can be used to render custom loading/error states | (props: RenderImageProps) => JSX.Element |
() => Image |
renderPage? |
Callback that can be used to render custom page. Can be used to display some non-image pages such as Video, for instance | (props: ImageRendererProps<T>, index: number) => JSX.Element |
ImageTransformer |
Prop | Description | Type | Is worklet? | Default |
---|---|---|---|---|
onIndexChange? |
Fires when active index changes | (nextIndex: number) => void |
Function or Worklet |
undefined |
onTap? |
Executes when tap image transformer receives tap | () => void |
Function or Worklet |
undefined |
onDoubleTap? |
Executes when tap image transformer receives double-tap | () => void |
Function or Worklet |
undefined |
onInteraction? |
Is called when either pan or scale has happened. | (type: 'scale' or 'pan') => void |
Function or Worklet |
undefined |
onPagerTranslateChange? |
Executes on pager's horizontal pan | (translateX: number) => void |
Function or Worklet |
undefined |
onGesture? |
Executes on pager's gesture | (event: PanGestureHandlerGestureEvent, isActive: SharedValue<boolean>) => void |
Function or Worklet |
undefined |
shouldPagerHandleGestureEvent? |
Worklet that will be passed to pager's shouldHandleEvent to determine should pager handle this event. Can be used to handle "swipe down to close". |
(event: PanGestureHandlerGestureEvent) => boolean |
Only Worklet |
undefined |
Name | Description | Type |
---|---|---|
goNext |
Changes the active index forward | () => void |
goBack |
Changes the active index backward | () => void |
setIndex |
Sets the active index | (nextIndex: number) => void |
WIP
WIP
The source code for the example (showcase) app is under the Example/
directory.
Clone the repo, go to the Example/ folder and run:
npm install
Before running the app, install the cocoapods dependencies:
npx pod-install
Now, you can start the app:
npm run ios
npm run android