react-native-calendar-kit icon indicating copy to clipboard operation
react-native-calendar-kit copied to clipboard

allowPinchToZoom slow?

Open joaobsantos opened this issue 2 years ago • 9 comments

Hi guys, thank you for the amazing work in this package...

Im gettin really low fps on pinchToZoom, on a high end device... Have you noticed this?

Thx in advanced

joaobsantos avatar Jun 19 '23 18:06 joaobsantos

I figure out the problem. I'll make another issue more detailed. Thx

joaobsantos avatar Nov 15 '23 09:11 joaobsantos

hi @joaobsantos can you share how did you figure it out? thank you!

mykel-unwritten avatar May 15 '24 19:05 mykel-unwritten

hi @joaobsantos can you share how did you figure it out? thank you!

If your app still doesn't need drag-and-drop features. You can try the alpha version, this is the version being rewritten from the beginning. There are no official documents yet, you will need to rely on example. But I guarantee it will be much smoother

Demo:

https://github.com/howljs/react-native-calendar-kit/assets/33460888/4564cd09-8c5c-4f35-bad0-d42003a6a1a5

Example: https://github.com/howljs/react-native-calendar-kit/tree/develop/example Npm: https://www.npmjs.com/package/@howljs/calendar-kit/v/2.0.0-alpha.0

howljs avatar May 15 '24 19:05 howljs

thank you for the swift response!

mykel-unwritten avatar May 15 '24 20:05 mykel-unwritten

@howljs thank you for the response, I've already tried the alpha it looks amazing for being a alpha.

But in this case I was talking abou the allowPinchToZoom prop, looking at it now maybe its not a fps problem, maybe its a rerender of the rowsize problem.

I've anexed a video and it flickers the rows lines when zooming. Also if you pinch in the 19:00 it goes to the, 9:00 zoomed. I was looking for a behavior similar to google calendar app, but maybe thats unrealistic to do in react native.

Either way, thank you so much for your time, and if someday this is production ready I'll support you with money.

pinch to zoom.webm

joaobsantos avatar May 21 '24 12:05 joaobsantos

@howljs thank you for the response, I've already tried the alpha it looks amazing for being a alpha.

But in this case I was talking abou the allowPinchToZoom prop, looking at it now maybe its not a fps problem, maybe its a rerender of the rowsize problem.

I've anexed a video and it flickers the rows lines when zooming. Also if you pinch in the 19:00 it goes to the, 9:00 zoomed.

I was looking for a behavior similar to google calendar app, but maybe thats unrealistic to do in react native.

Either way, thank you so much for your time, and if someday this is production ready I'll support you with money.

pinch to zoom.webm

Are you running the application in debug or release mode? On the Android side, if you run the application in debug mode, it will not perform smoothly. If it appears in release mode, I will need to check and update further.

howljs avatar May 21 '24 13:05 howljs

Ok thx, later today I will run a build to check it, ill report after :)

joaobsantos avatar May 21 '24 13:05 joaobsantos

Hi @howljs , sorry for the delay, but only had time to test it now.

So I've build the app and the problem persists.

Im no expert but I dont think thats a performance problem, I think when we pinch to zoom the scroll is also in effect giving that jittering effect, because the view goes up and down really fast.

Tell me if theres something I can do to help.

joaobsantos avatar May 25 '24 08:05 joaobsantos

hi @howljs so I've been trying to fix the issue and heres the code that fix the lag for me:

I change usePinchToZoom, the problem is that it sill goes up the scrollView, so if you try to focus 18:00 it scrolls almost to 7:00 am, I've tried to listen where the fingers are and adjust but I couldn't do it.

hope this helps a little bit, thx again.

import { useRef } from 'react';
import { Gesture, type GestureType } from 'react-native-gesture-handler';
import { useSharedValue, withTiming } from 'react-native-reanimated';
import { useCalendar } from '../context/CalendarProvider';
import { clampValues } from '../utils/utils';

const usePinchToZoom = () => {
  const {
    verticalListRef,
    maxTimeIntervalHeight,
    minTimeIntervalHeight,
    timeIntervalHeight,
    offsetY,
    allowPinchToZoom,
  } = useCalendar();

  const pinchGestureRef = useRef<GestureType>();
  const startScale = useSharedValue(0);
  const lastScrollTime = useRef(0);

  const pinchGesture = Gesture.Pinch()
    .onBegin(({ scale }) => {
      startScale.value = scale;
    })
    .onUpdate(({ focalY, scale, velocity }) => {
      const diffScale = startScale.value - scale;
      const newScale = 1 - diffScale;
      const max = maxTimeIntervalHeight + 16;
      const min = minTimeIntervalHeight - 16;
      const nextHeight = newScale * timeIntervalHeight.value;
      startScale.value = scale;
      if (nextHeight > max || nextHeight < min || velocity === 0) {
        return;
      }
      timeIntervalHeight.value = nextHeight;

      // Throttle scroll updates to prevent excessive updates
      const now = Date.now();
      if (now - lastScrollTime.current > 16) {
        lastScrollTime.current = now;
        const deltaY = offsetY.value + focalY;
        const newOffsetY = offsetY.value - deltaY * (1 - newScale);
        verticalListRef.current?.scrollTo({
          y: newOffsetY,
          animated: false,
        });
      }
    })
    .onEnd(({ focalY }) => {
      const nextHeight = clampValues(
        timeIntervalHeight.value,
        minTimeIntervalHeight,
        maxTimeIntervalHeight
      );
      const newScale = nextHeight / timeIntervalHeight.value;
      if (newScale === 1) {
        return;
      }
      timeIntervalHeight.value = withTiming(nextHeight, { duration: 250 });
      const deltaY = offsetY.value + focalY;
      const newOffsetY = offsetY.value - deltaY * (1 - newScale);
      verticalListRef.current?.scrollTo({
        y: newOffsetY,
        animated: true,
      });
    })
    .enabled(allowPinchToZoom)
    .withRef(pinchGestureRef);

  return { pinchGesture, pinchGestureRef };
};

export default usePinchToZoom;

joaobsantos avatar May 31 '24 15:05 joaobsantos

Fixed in v2.0.0, please check it again

howljs avatar Sep 24 '24 09:09 howljs

Thank you for your work @howljs :)

joaobsantos avatar Sep 24 '24 11:09 joaobsantos