Use safe aspect for lightbox calculations

This commit is contained in:
Dan Abramov
2024-11-01 03:04:21 +00:00
parent c95f8e8659
commit 5e1a2fcf06
2 changed files with 10 additions and 13 deletions
@@ -52,7 +52,7 @@ const ImageItem = ({
isScrollViewBeingDragged, isScrollViewBeingDragged,
}: Props) => { }: Props) => {
const [isScaled, setIsScaled] = useState(false) const [isScaled, setIsScaled] = useState(false)
const [_aspectRatio, imageDimensions] = useImageDimensions({ const [imageAspect, imageDimensions] = useImageDimensions({
src: imageSrc.uri, src: imageSrc.uri,
knownDimensions: imageSrc.dimensions, knownDimensions: imageSrc.dimensions,
}) })
@@ -122,12 +122,12 @@ const ImageItem = ({
candidateTransform: TransformMatrix, candidateTransform: TransformMatrix,
) { ) {
'worklet' 'worklet'
if (!imageDimensions) { if (!imageAspect) {
return [0, 0] return [0, 0]
} }
const [nextTranslateX, nextTranslateY, nextScale] = const [nextTranslateX, nextTranslateY, nextScale] =
readTransform(candidateTransform) readTransform(candidateTransform)
const scaledDimensions = getScaledDimensions(imageDimensions, nextScale) const scaledDimensions = getScaledDimensions(imageAspect, nextScale)
const clampedTranslateX = clampTranslation( const clampedTranslateX = clampTranslation(
nextTranslateX, nextTranslateX,
scaledDimensions.width, scaledDimensions.width,
@@ -251,7 +251,7 @@ const ImageItem = ({
.numberOfTaps(2) .numberOfTaps(2)
.onEnd(e => { .onEnd(e => {
'worklet' 'worklet'
if (!imageDimensions) { if (!imageDimensions || !imageAspect) {
return return
} }
const [, , committedScale] = readTransform(committedTransform.value) const [, , committedScale] = readTransform(committedTransform.value)
@@ -263,7 +263,6 @@ const ImageItem = ({
} }
// Try to zoom in so that we get rid of the black bars (whatever the orientation was). // Try to zoom in so that we get rid of the black bars (whatever the orientation was).
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height const screenAspect = SCREEN.width / SCREEN.height
const candidateScale = Math.max( const candidateScale = Math.max(
imageAspect / screenAspect, imageAspect / screenAspect,
@@ -366,11 +365,10 @@ const styles = StyleSheet.create({
}) })
function getScaledDimensions( function getScaledDimensions(
imageDimensions: ImageDimensions, imageAspect: number,
scale: number, scale: number,
): ImageDimensions { ): ImageDimensions {
'worklet' 'worklet'
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height const screenAspect = SCREEN.width / SCREEN.height
const isLandscape = imageAspect > screenAspect const isLandscape = imageAspect > screenAspect
if (isLandscape) { if (isLandscape) {
@@ -20,7 +20,7 @@ import {Image} from 'expo-image'
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
import {useImageDimensions} from '#/lib/media/image-sizes' import {useImageDimensions} from '#/lib/media/image-sizes'
import {Dimensions as ImageDimensions, ImageSource} from '../../@types' import {ImageSource} from '../../@types'
const SWIPE_CLOSE_OFFSET = 75 const SWIPE_CLOSE_OFFSET = 75
const SWIPE_CLOSE_VELOCITY = 1 const SWIPE_CLOSE_VELOCITY = 1
@@ -47,7 +47,7 @@ const ImageItem = ({
const scrollViewRef = useAnimatedRef<Animated.ScrollView>() const scrollViewRef = useAnimatedRef<Animated.ScrollView>()
const translationY = useSharedValue(0) const translationY = useSharedValue(0)
const [scaled, setScaled] = useState(false) const [scaled, setScaled] = useState(false)
const [_aspectRatio, imageDimensions] = useImageDimensions({ const [imageAspect, imageDimensions] = useImageDimensions({
src: imageSrc.uri, src: imageSrc.uri,
knownDimensions: imageSrc.dimensions, knownDimensions: imageSrc.dimensions,
}) })
@@ -102,7 +102,7 @@ const ImageItem = ({
const willZoom = !scaled const willZoom = !scaled
if (willZoom) { if (willZoom) {
nextZoomRect = getZoomRectAfterDoubleTap( nextZoomRect = getZoomRectAfterDoubleTap(
imageDimensions, imageAspect,
absoluteX, absoluteX,
absoluteY, absoluteY,
) )
@@ -182,7 +182,7 @@ const styles = StyleSheet.create({
}) })
const getZoomRectAfterDoubleTap = ( const getZoomRectAfterDoubleTap = (
imageDimensions: ImageDimensions | undefined, imageAspect: number | undefined,
touchX: number, touchX: number,
touchY: number, touchY: number,
): { ): {
@@ -191,7 +191,7 @@ const getZoomRectAfterDoubleTap = (
width: number width: number
height: number height: number
} => { } => {
if (!imageDimensions) { if (!imageAspect) {
return { return {
x: 0, x: 0,
y: 0, y: 0,
@@ -202,7 +202,6 @@ const getZoomRectAfterDoubleTap = (
// First, let's figure out how much we want to zoom in. // First, let's figure out how much we want to zoom in.
// We want to try to zoom in at least close enough to get rid of black bars. // We want to try to zoom in at least close enough to get rid of black bars.
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height const screenAspect = SCREEN.width / SCREEN.height
const zoom = Math.max( const zoom = Math.max(
imageAspect / screenAspect, imageAspect / screenAspect,