Remove null checks for measurements

This commit is contained in:
Dan Abramov
2024-11-07 11:23:26 +00:00
parent d087565813
commit 0110552183
4 changed files with 66 additions and 36 deletions
@@ -1,13 +1,11 @@
import React, {useState} from 'react'
import {ActivityIndicator, StyleProp, StyleSheet, View} from 'react-native'
import {ActivityIndicator, StyleProp, StyleSheet} from 'react-native'
import {
Gesture,
GestureDetector,
PanGesture,
} from 'react-native-gesture-handler'
import Animated, {
AnimatedRef,
measure,
runOnJS,
useAnimatedReaction,
useAnimatedRef,
@@ -42,7 +40,12 @@ type Props = {
onZoom: (isZoomed: boolean) => void
isScrollViewBeingDragged: boolean
showControls: boolean
safeAreaRef: AnimatedRef<View>
measureSafeArea: () => {
x: number
y: number
width: number
height: number
}
imageAspect: number | undefined
imageDimensions: ImageDimensions | undefined
imageStyle: StyleProp<ImageStyle>
@@ -53,7 +56,7 @@ const ImageItem = ({
onTap,
onZoom,
isScrollViewBeingDragged,
safeAreaRef,
measureSafeArea,
imageAspect,
imageDimensions,
imageStyle,
@@ -143,10 +146,7 @@ const ImageItem = ({
const pinch = Gesture.Pinch()
.onStart(e => {
'worklet'
const screenSize = measure(safeAreaRef)
if (!screenSize) {
return
}
const screenSize = measureSafeArea()
pinchOrigin.value = {
x: e.focalX - screenSize.width / 2,
y: e.focalY - screenSize.height / 2,
@@ -154,8 +154,8 @@ const ImageItem = ({
})
.onChange(e => {
'worklet'
const screenSize = measure(safeAreaRef)
if (!imageDimensions || !screenSize) {
const screenSize = measureSafeArea()
if (!imageDimensions) {
return
}
// Don't let the picture zoom in so close that it gets blurry.
@@ -213,8 +213,8 @@ const ImageItem = ({
.minPointers(isScaled ? 1 : 2)
.onChange(e => {
'worklet'
const screenSize = measure(safeAreaRef)
if (!imageDimensions || !screenSize) {
const screenSize = measureSafeArea()
if (!imageDimensions) {
return
}
@@ -257,8 +257,8 @@ const ImageItem = ({
.numberOfTaps(2)
.onEnd(e => {
'worklet'
const screenSize = measure(safeAreaRef)
if (!imageDimensions || !imageAspect || !screenSize) {
const screenSize = measureSafeArea()
if (!imageDimensions || !imageAspect) {
return
}
const [, , committedScale] = readTransform(committedTransform.value)
@@ -7,18 +7,13 @@
*/
import React, {useState} from 'react'
import {ActivityIndicator, StyleProp, StyleSheet, View} from 'react-native'
import {ActivityIndicator, StyleProp, StyleSheet} from 'react-native'
import {
Gesture,
GestureDetector,
PanGesture,
} from 'react-native-gesture-handler'
import Animated, {
AnimatedRef,
measure,
runOnJS,
useAnimatedRef,
} from 'react-native-reanimated'
import Animated, {runOnJS, useAnimatedRef} from 'react-native-reanimated'
import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {Image, ImageStyle} from 'expo-image'
@@ -37,7 +32,12 @@ type Props = {
onZoom: (scaled: boolean) => void
isScrollViewBeingDragged: boolean
showControls: boolean
safeAreaRef: AnimatedRef<View>
measureSafeArea: () => {
x: number
y: number
width: number
height: number
}
imageAspect: number | undefined
imageDimensions: ImageDimensions | undefined
imageStyle: StyleProp<ImageStyle>
@@ -49,7 +49,7 @@ const ImageItem = ({
onTap,
onZoom,
showControls,
safeAreaRef,
measureSafeArea,
imageAspect,
imageDimensions,
imageStyle,
@@ -103,10 +103,7 @@ const ImageItem = ({
.numberOfTaps(2)
.onEnd(e => {
'worklet'
const screenSize = measure(safeAreaRef)
if (!screenSize) {
return
}
const screenSize = measureSafeArea()
const {absoluteX, absoluteY} = e
let nextZoomRect = {
x: 0,
@@ -3,7 +3,6 @@
import React from 'react'
import {ImageStyle, StyleProp, View} from 'react-native'
import {PanGesture} from 'react-native-gesture-handler'
import {AnimatedRef} from 'react-native-reanimated'
import {Dimensions as ImageDimensions, ImageSource} from '../../@types'
@@ -14,7 +13,12 @@ type Props = {
onZoom: (scaled: boolean) => void
isScrollViewBeingDragged: boolean
showControls: boolean
safeAreaRef: AnimatedRef<View>
measureSafeArea: () => {
x: number
y: number
width: number
height: number
}
imageAspect: number | undefined
imageDimensions: ImageDimensions | undefined
imageStyle: StyleProp<ImageStyle>
+35 -6
View File
@@ -33,7 +33,12 @@ import Animated, {
withDecay,
withSpring,
} from 'react-native-reanimated'
import {Edge, SafeAreaView} from 'react-native-safe-area-context'
import {
Edge,
SafeAreaView,
useSafeAreaFrame,
useSafeAreaInsets,
} from 'react-native-safe-area-context'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Trans} from '@lingui/macro'
@@ -49,6 +54,8 @@ import {ImageSource} from './@types'
import ImageDefaultHeader from './components/ImageDefaultHeader'
import ImageItem from './components/ImageItem/ImageItem'
type Rect = {x: number; y: number; width: number; height: number}
const PIXEL_RATIO = PixelRatio.get()
const SLOW_SPRING = {stiffness: 120}
const FAST_SPRING = {stiffness: 700}
@@ -340,13 +347,35 @@ function LightboxImage({
knownDimensions: imageSrc.dimensions,
})
const safeFrameDelayedForJSThreadOnly = useSafeAreaFrame()
const safeInsetsDelayedForJSThreadOnly = useSafeAreaInsets()
const measureSafeArea = React.useCallback(() => {
'worklet'
let safeArea: Rect | null = measure(safeAreaRef)
if (!safeArea) {
if (_WORKLET) {
console.error('Expected to always be able to measure safe area.')
}
const frame = safeFrameDelayedForJSThreadOnly
const insets = safeInsetsDelayedForJSThreadOnly
safeArea = {
x: frame.x + insets.left,
y: frame.y + insets.top,
width: frame.width - insets.left - insets.right,
height: frame.height - insets.top - insets.bottom,
}
}
return safeArea
}, [
safeFrameDelayedForJSThreadOnly,
safeInsetsDelayedForJSThreadOnly,
safeAreaRef,
])
const {thumbRect, dimensions} = imageSrc
const interpolation = useDerivedValue(() => {
'worklet'
const safeArea = measure(safeAreaRef)
if (!safeArea) {
return {transform: [], width: 0, height: 0}
}
const safeArea = measureSafeArea()
const finalWidth = safeArea.width
const finalHeight = imageAspect ? safeArea.width / imageAspect : undefined
if (isActive && thumbRect && dimensions && openProgress.value < 1) {
@@ -431,7 +460,7 @@ function LightboxImage({
onRequestClose={onRequestClose}
isScrollViewBeingDragged={isScrollViewBeingDragged}
showControls={showControls}
safeAreaRef={safeAreaRef}
measureSafeArea={measureSafeArea}
imageAspect={imageAspect}
imageDimensions={imageDimensions}
imageStyle={imageStyle}