Animate opening

This commit is contained in:
Dan Abramov
2024-10-31 00:34:19 +00:00
parent 0be8c55780
commit d35fcca01e
+50 -10
View File
@@ -57,24 +57,29 @@ const SCREEN_HEIGHT = Dimensions.get('window').height
function ImageViewing({
images,
thumbDims: _thumbDims, // TODO: Pass down and use for animation.
thumbDims,
initialImageIndex,
visible,
onRequestClose,
onPressSave,
onPressShare,
}: Props) {
const openProgress = useSharedValue(0)
React.useEffect(() => {
openProgress.value = withClampedSpring(1)
}, [openProgress])
const [isScaled, setIsScaled] = useState(false)
const [isDragging, setIsDragging] = useState(false)
const [imageIndex, setImageIndex] = useState(initialImageIndex)
const [showControls, setShowControls] = useState(true)
const dismissSwipeTranslateY = useSharedValue(0)
const animatedHeaderStyle = useAnimatedStyle(() => {
const show = showControls && dismissSwipeTranslateY.value === 0
return {
pointerEvents: show ? 'auto' : 'none',
opacity: withClampedSpring(show ? 1 : 0),
opacity: withClampedSpring(show && openProgress.value > 0 ? 1 : 0),
transform: [
{
translateY: withClampedSpring(show ? 0 : -30),
@@ -86,7 +91,7 @@ function ImageViewing({
const show = showControls && dismissSwipeTranslateY.value === 0
return {
pointerEvents: show ? 'auto' : 'none',
opacity: withClampedSpring(show ? 1 : 0),
opacity: withClampedSpring(show && openProgress.value > 0 ? 1 : 0),
transform: [
{
translateY: withClampedSpring(show ? 0 : 30),
@@ -95,6 +100,9 @@ function ImageViewing({
}
})
// TODO: Apply transform
// const initialTransform = calculateOverlayTransform(SCREEN, thumbDims)
const dismissSwipePan = Gesture.Pan()
.enabled(!isScaled)
.activeOffsetY([-10, 10])
@@ -137,13 +145,18 @@ function ImageViewing({
}, [])
const backdropStyle = useAnimatedStyle(() => {
const dismissProgress = Math.min(
Math.abs(dismissSwipeTranslateY.value) / (SCREEN.height / 2),
1,
)
return {
opacity: 1 - dismissProgress,
let opacity
if (openProgress.value < 1) {
opacity = openProgress.value
} else {
opacity =
1 -
Math.min(
Math.abs(dismissSwipeTranslateY.value) / (SCREEN.height / 2),
1,
)
}
return {opacity}
})
const activeImageStyle = useAnimatedStyle(() => {
return {
@@ -290,6 +303,33 @@ function LightboxFooter({
)
}
function calculateOverlayTransform(
screenSize: {width: number; height: number},
thumbnailPlacement:
| {
pageX: number
width: number
pageY: number
height: number
}
| null
| undefined,
) {
if (!thumbnailPlacement) {
return null
}
const scale = thumbnailPlacement.width / screenSize.width
const screenCenterX = screenSize.width / 2
const screenCenterY = screenSize.height / 2
const thumbnailCenterX =
thumbnailPlacement.pageX + thumbnailPlacement.width / 2
const thumbnailCenterY =
thumbnailPlacement.pageY + thumbnailPlacement.height / 2
const translateX = (thumbnailCenterX - screenCenterX) / scale
const translateY = (thumbnailCenterY - screenCenterY) / scale
return {scale, translateX, translateY}
}
const styles = StyleSheet.create({
screen: {
position: 'absolute',