Rewrite Android lightbox (#1624)

This commit is contained in:
dan 2023-10-06 03:54:36 +01:00 committed by GitHub
parent 8366fe2c4a
commit 64153067e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 540 additions and 598 deletions

View file

@ -6,7 +6,7 @@
*
*/
import React, {useCallback, useRef, useState} from 'react'
import React, {MutableRefObject, useCallback, useRef, useState} from 'react'
import {
Animated,
@ -20,11 +20,11 @@ import {
TouchableWithoutFeedback,
} from 'react-native'
import {Image} from 'expo-image'
import {GestureType} from 'react-native-gesture-handler'
import useImageDimensions from '../../hooks/useImageDimensions'
import {getImageTransform} from '../../utils'
import {ImageSource} from '../../@types'
import {ImageSource, Dimensions as ImageDimensions} from '../../@types'
import {ImageLoading} from './ImageLoading'
const DOUBLE_TAP_DELAY = 300
@ -40,6 +40,8 @@ type Props = {
imageSrc: ImageSource
onRequestClose: () => void
onZoom: (scaled: boolean) => void
pinchGestureRef: MutableRefObject<GestureType>
isScrollViewBeingDragged: boolean
}
const AnimatedImage = Animated.createAnimatedComponent(Image)
@ -164,7 +166,7 @@ const styles = StyleSheet.create({
})
const getZoomRectAfterDoubleTap = (
imageDimensions: {width: number; height: number} | null,
imageDimensions: ImageDimensions | null,
touchX: number,
touchY: number,
): {
@ -252,7 +254,7 @@ const getZoomRectAfterDoubleTap = (
}
const getImageStyles = (
image: {width: number; height: number} | null,
image: ImageDimensions | null,
translate: {readonly x: number; readonly y: number} | undefined,
scale?: number,
) => {
@ -275,4 +277,37 @@ const getImageStyles = (
}
}
const getImageTransform = (
image: ImageDimensions | null,
screen: ImageDimensions,
) => {
if (!image?.width || !image?.height) {
return [] as const
}
const wScale = screen.width / image.width
const hScale = screen.height / image.height
const scale = Math.min(wScale, hScale)
const {x, y} = getImageTranslate(image, screen)
return [{x, y}, scale] as const
}
const getImageTranslate = (
image: ImageDimensions,
screen: ImageDimensions,
): {x: number; y: number} => {
const getTranslateForAxis = (axis: 'x' | 'y'): number => {
const imageSize = axis === 'x' ? image.width : image.height
const screenSize = axis === 'x' ? screen.width : screen.height
return (screenSize - imageSize) / 2
}
return {
x: getTranslateForAxis('x'),
y: getTranslateForAxis('y'),
}
}
export default React.memo(ImageItem)