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,
}: Props) => {
const [isScaled, setIsScaled] = useState(false)
const [_aspectRatio, imageDimensions] = useImageDimensions({
const [imageAspect, imageDimensions] = useImageDimensions({
src: imageSrc.uri,
knownDimensions: imageSrc.dimensions,
})
@@ -122,12 +122,12 @@ const ImageItem = ({
candidateTransform: TransformMatrix,
) {
'worklet'
if (!imageDimensions) {
if (!imageAspect) {
return [0, 0]
}
const [nextTranslateX, nextTranslateY, nextScale] =
readTransform(candidateTransform)
const scaledDimensions = getScaledDimensions(imageDimensions, nextScale)
const scaledDimensions = getScaledDimensions(imageAspect, nextScale)
const clampedTranslateX = clampTranslation(
nextTranslateX,
scaledDimensions.width,
@@ -251,7 +251,7 @@ const ImageItem = ({
.numberOfTaps(2)
.onEnd(e => {
'worklet'
if (!imageDimensions) {
if (!imageDimensions || !imageAspect) {
return
}
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).
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height
const candidateScale = Math.max(
imageAspect / screenAspect,
@@ -366,11 +365,10 @@ const styles = StyleSheet.create({
})
function getScaledDimensions(
imageDimensions: ImageDimensions,
imageAspect: number,
scale: number,
): ImageDimensions {
'worklet'
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height
const isLandscape = imageAspect > screenAspect
if (isLandscape) {
@@ -20,7 +20,7 @@ import {Image} from 'expo-image'
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
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_VELOCITY = 1
@@ -47,7 +47,7 @@ const ImageItem = ({
const scrollViewRef = useAnimatedRef<Animated.ScrollView>()
const translationY = useSharedValue(0)
const [scaled, setScaled] = useState(false)
const [_aspectRatio, imageDimensions] = useImageDimensions({
const [imageAspect, imageDimensions] = useImageDimensions({
src: imageSrc.uri,
knownDimensions: imageSrc.dimensions,
})
@@ -102,7 +102,7 @@ const ImageItem = ({
const willZoom = !scaled
if (willZoom) {
nextZoomRect = getZoomRectAfterDoubleTap(
imageDimensions,
imageAspect,
absoluteX,
absoluteY,
)
@@ -182,7 +182,7 @@ const styles = StyleSheet.create({
})
const getZoomRectAfterDoubleTap = (
imageDimensions: ImageDimensions | undefined,
imageAspect: number | undefined,
touchX: number,
touchY: number,
): {
@@ -191,7 +191,7 @@ const getZoomRectAfterDoubleTap = (
width: number
height: number
} => {
if (!imageDimensions) {
if (!imageAspect) {
return {
x: 0,
y: 0,
@@ -202,7 +202,6 @@ const getZoomRectAfterDoubleTap = (
// 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.
const imageAspect = imageDimensions.width / imageDimensions.height
const screenAspect = SCREEN.width / SCREEN.height
const zoom = Math.max(
imageAspect / screenAspect,