Closed lucianomlima closed 1 month ago
Hi there, did you try this issue in isolation? Like the example described on ResumableZoom
docs? What you mention here is something way too specific.
Making random guesses before I know your answer, from my perspective it looks like useWindowDimensions
runs faster than the device orientation change callback, I say this because the image in the video clearly gets wider.
Did you try to request the new width as the orientation is set, like so:
const [width, setWidth] = useState<number>(Dimensions.get("window").width);
....
const onOrientationChange = useCallback((orientation: OrientationType) => {
currentOrientation.current = orientation;
setWidth(Dimensions.get("window").width);
}, []);
Thank you for the answer. Yeah, I'm construct this case in isolation. First I did mount the Gallery, then I put the images inside ResumableZoom with pinch and double tap gestures enabled and now I'm trying to integrate with orientation changes.
For the previous steps I did make work properly. But you give me more insights to try. I'll try them and answer back here later.
Currently I can only think of a way to make this work but I can not put it to the test myself because the version on my computer of this library is really broken right now, however try it and let me know.
Pretty much is about preventing a rerender when the orientation changes, Pinchable views are heavy components, so I'd advise you to place your size changing logic within the only place it makes sense to me, on the onLayout callback:
Be sure to try out the gestures, as I said the version I have is quite broken right now because of Expo.
TDLR: I deleted the project and cloned it, it works like a charm for me and do not forget to reset transformations on onLayout changes.
I'm sorry for the wait. I was in the hospital for the past three days. I will try your suggestion today. Thank you!
After some time coding and searching I found that the root cause is the SafeArea. Even using safeAreaInsets directly, when orientation changes, insets are updated more than once and with several different values combinations.
I ended up coding a in house solution to define insets using ref to avoid rerendering. Thanks for the support.
Summary
Hello! I'm working on a photo gallery with
react-native-snap-carousel
that allows changing orientation withreact-native-orientation-locker
.Gallery component
```ts import React, { useCallback, useEffect, useState, useRef, memo, startTransition, } from 'react'; import { useWindowDimensions } from 'react-native'; import { Box } from '@gympass/yoga'; import { useNavigation, type ParamListBase } from '@react-navigation/native'; import type { StackNavigationProp } from '@react-navigation/stack'; import { useConfig } from 'hooks/remoteConfig'; import tracker from 'services/tracker'; import Dots from './components/Dots'; import { Photo, type PhotoItem } from './components/Photo'; import { Loading, Carousel } from './styles'; export type GalleryProps = { index: number; photos: ArrayWhen the orientation changes from portrait to landscape, I must update the image dimensions to fit on the screen.
Photo component
```ts import React, { useCallback, useEffect, useRef } from 'react'; import { Image, useWindowDimensions, type LayoutChangeEvent, } from 'react-native'; import { Box } from '@gympass/yoga'; import Orientation, { OrientationType } from 'react-native-orientation-locker'; import { runOnJS } from 'react-native-reanimated'; import { ResumableZoom, getAspectRatioSize, useImageResolution, type CommonZoomState, type ResumableZoomProps, } from 'react-native-zoom-toolkit'; import { Loading } from '../styles'; export type PhotoItem = { id: string; uri: string; }; export type PhotoProps = { item: PhotoItem; panEnabled: boolean; onZoomUpdate: (scale: number) => void; } & ResumableZoomProps; export function Photo({ item, panEnabled = false, onZoomUpdate, ...zoomProps }: ReadonlyBut when it changes to the landscape orientation (right or left), there is a quick image flicker that gets bigger and then go to its desired size.
image-flickering.webm
Do you know if there is any way I can animate this change in width/height so that this flicker is not visible? As the Zoom toolkit uses
react-native-animated
, I think it's possible to animate the transition, but I can't find a way.