Control width/height from interpolation

This commit is contained in:
Dan Abramov
2024-11-02 19:06:31 +00:00
parent b3f4338d21
commit 95615d47f6
4 changed files with 49 additions and 37 deletions
@@ -1,5 +1,10 @@
import React, {useState} from 'react' import React, {useState} from 'react'
import {ActivityIndicator, Dimensions, StyleSheet} from 'react-native' import {
ActivityIndicator,
Dimensions,
StyleProp,
StyleSheet,
} from 'react-native'
import { import {
Gesture, Gesture,
GestureDetector, GestureDetector,
@@ -49,7 +54,7 @@ type Props = {
isScrollViewBeingDragged: boolean isScrollViewBeingDragged: boolean
showControls: boolean showControls: boolean
dismissSwipePan: PanGesture dismissSwipePan: PanGesture
animatedStyle: ImageStyle | null animatedStyle: StyleProp<ImageStyle>
} }
const ImageItem = ({ const ImageItem = ({
imageSrc, imageSrc,
@@ -301,27 +306,22 @@ const ImageItem = ({
<Animated.View <Animated.View
ref={containerRef} ref={containerRef}
style={[styles.container, animatedContainerStyle, {}]}> style={[styles.container, animatedContainerStyle, {}]}>
<Animated.View <Animated.View style={animatedStyle}>
style={[
animatedStyle,
{
width: SCREEN.width,
height: imageAspect ? SCREEN.width / imageAspect : undefined,
borderRadius:
imageSrc.type === 'circle-avi'
? SCREEN.width / 2
: imageSrc.type === 'rect-avi'
? 20
: 0,
},
]}>
<ActivityIndicator size="small" color="#FFF" style={styles.loading} /> <ActivityIndicator size="small" color="#FFF" style={styles.loading} />
<AnimatedImage <AnimatedImage
contentFit="contain" contentFit="contain"
source={{uri: imageSrc.uri}} source={{uri: imageSrc.uri}}
placeholderContentFit="contain" placeholderContentFit="contain"
placeholder={{uri: imageSrc.thumbUri}} placeholder={{uri: imageSrc.thumbUri}}
style={{flex: 1}} style={{
flex: 1,
borderRadius:
imageSrc.type === 'circle-avi'
? SCREEN.width / 2
: imageSrc.type === 'rect-avi'
? 20
: 0,
}}
accessibilityLabel={imageSrc.alt} accessibilityLabel={imageSrc.alt}
accessibilityHint="" accessibilityHint=""
accessibilityIgnoresInvertColors accessibilityIgnoresInvertColors
@@ -7,7 +7,12 @@
*/ */
import React, {useState} from 'react' import React, {useState} from 'react'
import {ActivityIndicator, Dimensions, StyleSheet} from 'react-native' import {
ActivityIndicator,
Dimensions,
StyleProp,
StyleSheet,
} from 'react-native'
import { import {
Gesture, Gesture,
GestureDetector, GestureDetector,
@@ -34,7 +39,7 @@ type Props = {
isScrollViewBeingDragged: boolean isScrollViewBeingDragged: boolean
showControls: boolean showControls: boolean
dismissSwipePan: PanGesture | null dismissSwipePan: PanGesture | null
animatedStyle: ImageStyle | null animatedStyle: StyleProp<ImageStyle>
} }
const ImageItem = ({ const ImageItem = ({
@@ -132,20 +137,7 @@ const ImageItem = ({
onScroll={scrollHandler} onScroll={scrollHandler}
bounces={scaled} bounces={scaled}
centerContent> centerContent>
<Animated.View <Animated.View style={animatedStyle}>
style={[
animatedStyle,
{
width: SCREEN.width,
height: imageAspect ? SCREEN.width / imageAspect : undefined,
borderRadius:
imageSrc.type === 'circle-avi'
? SCREEN.width / 2
: imageSrc.type === 'rect-avi'
? 20
: 0,
},
]}>
<ActivityIndicator size="small" color="#FFF" style={styles.loading} /> <ActivityIndicator size="small" color="#FFF" style={styles.loading} />
<AnimatedImage <AnimatedImage
contentFit="cover" contentFit="cover"
@@ -156,7 +148,15 @@ const ImageItem = ({
accessibilityHint="" accessibilityHint=""
enableLiveTextInteraction={showControls && !scaled} enableLiveTextInteraction={showControls && !scaled}
accessibilityIgnoresInvertColors accessibilityIgnoresInvertColors
style={{flex: 1}} style={{
flex: 1,
borderRadius:
imageSrc.type === 'circle-avi'
? SCREEN.width / 2
: imageSrc.type === 'rect-avi'
? 20
: 0,
}}
/> />
</Animated.View> </Animated.View>
</Animated.ScrollView> </Animated.ScrollView>
@@ -1,7 +1,7 @@
// default implementation fallback for web // default implementation fallback for web
import React from 'react' import React from 'react'
import {View} from 'react-native' import {StyleProp, View} from 'react-native'
import {PanGesture} from 'react-native-gesture-handler' import {PanGesture} from 'react-native-gesture-handler'
import {ImageStyle} from 'expo-image' import {ImageStyle} from 'expo-image'
@@ -15,7 +15,7 @@ type Props = {
isScrollViewBeingDragged: boolean isScrollViewBeingDragged: boolean
showControls: boolean showControls: boolean
dismissSwipePan: PanGesture | null dismissSwipePan: PanGesture | null
animatedStyle: ImageStyle | null animatedStyle: StyleProp<ImageStyle>
} }
const ImageItem = (_props: Props) => { const ImageItem = (_props: Props) => {
+13 -1
View File
@@ -107,12 +107,20 @@ function ImageViewing({
}) })
const activeImageStyle = useAnimatedStyle(() => { const activeImageStyle = useAnimatedStyle(() => {
const image = images[imageIndex]
const imageAspect = image.dimensions
? image.dimensions.width / image.dimensions.height
: null
const width = SCREEN.width
const height = imageAspect ? SCREEN.width / imageAspect : undefined
if (openProgress.value === 1 || dismissSwipeTranslateY.value !== 0) { if (openProgress.value === 1 || dismissSwipeTranslateY.value !== 0) {
return { return {
transform: [{translateY: dismissSwipeTranslateY.value}], transform: [{translateY: dismissSwipeTranslateY.value}],
width,
height,
} }
} }
const image = images[imageIndex]
if (image.thumbRect && image.dimensions) { if (image.thumbRect && image.dimensions) {
const interpolatedTransform = interpolateTransform( const interpolatedTransform = interpolateTransform(
openProgress.value, openProgress.value,
@@ -122,10 +130,14 @@ function ImageViewing({
) )
return { return {
transform: interpolatedTransform, transform: interpolatedTransform,
width,
height,
} }
} }
return { return {
transform: [], transform: [],
width,
height,
} }
}) })