DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
翻訳待ち
A React Native lightbox and image gallery that opens out of the photo you tap and closes back into it. Swipe, pinch zoom, swipe down to close, thumbnails, video. Works with Expo.
翻訳待ち
Loading the full README.
Read the full README ↗A lightbox for React Native. It opens out of the picture you tapped and closes back into it. iOS and Android, with or without Expo.
It's the phone version of react-motion-lightbox, which I built for my own site and for Gryt. Gryt's phone app is the first one to use this. The props have the same names wherever that made sense, so if you know one you know the other.
There's also Gallery, a small one for a chat message or a feed. It shows one picture at a time in a box, and a tap opens the lightbox out of it.
npm install react-native-motion-lightbox
You also need react-native-reanimated 4.5 or newer, react-native-gesture-handler 2.32 or newer, and react-native-worklets. In an Expo app, install them with npx expo install so you get versions that match your SDK. It doesn't use any Expo modules, so it works in a bare app too.
Your app needs a GestureHandlerRootView at the top, as Gesture Handler always does.
import { Gallery } from 'react-native-motion-lightbox'
<Gallery
items={[
{ kind: 'image', src: 'https://example.com/fjord.jpg', width: 5200, height: 3464, alt: 'A fjord' },
{ kind: 'image', src: 'https://example.com/harbour.jpg', width: 6000, height: 4000, alt: 'The harbour' },
]}
aspect={4 / 3}
fit="contain"
peek={28}
gap={6}
caption={(item) => item.alt}
onLongPress={(i) => openMessageMenu(i)}
/>
Swipe it, and tap a picture to open the lightbox. A swipe never counts as a tap. A swipe that goes mostly up or down is left to the screen, so a list around the gallery still scrolls.
It takes the same props as the lightbox and passes them on. On top of those:
| Prop | |
|---|---|
aspect | A picture's width over its height. Default 1, a square. |
fit | 'cover' (the default) fills the box with the part of each picture that focus and zoom pick. 'contain' shows the whole picture inside the box. |
peek | How many points of the next picture show at the right edge, so it reads as something to swipe. Default 0. |
gap | The space between pictures, in points. Default 12. |
onPress(index) | Called on a tap instead of opening the lightbox, if your app has a viewer of its own. |
onLongPress(index) | Called on a long press, for a menu. |
autoplay | Move on by itself every this many milliseconds, like 6000. Off by default. It holds while a finger is on it or the lightbox is open, and adds a pause button. |
style | Goes on the gallery's outer view. Give it a width, or let it fill its parent. |
Each picture can have a focus and a zoom. focus is the point the box centres on, as fractions across and down, and zoom is how far it zooms in on it. With fit="cover", the lightbox opens out of exactly that part and then shows the whole picture.
For a grid or a list of your own, measure the thumbnail when it opens and closes, and pass that as origin:
const cells = useRef<(View | null)[]>([])
const origin = (i: number) =>
new Promise<Rect | undefined>((resolve) => {
const cell = cells.current[i]
if (!cell) return resolve(undefined)
cell.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }))
})
<Lightbox
items={items}
index={index}
open={open}
onClose={() => setOpen(false)}
onIndexChange={setIndex}
origin={origin}
caption={(item) => item.alt}
/>
This is the beginning of the README. Read the rest at the original. Read the full README ↗