Repeat Reanimated Animation without using Web APIs (setInterval)

580 Views Asked by At

So I have an animation using React Native Reanimated that repeats every 3 seconds and updates the SharedValue. I have implemented it as shown below using setInterval.

const SomeThreshold = 5;

useEffect(() => {
  progress.value = 0;

  const interval = setInterval(() => {
    if (progress.value === SomeThreshold) {
      progress.value = 0;
      return;
    }

    progress.value = withTiming(progress.value + 1, {
      duration: 2000,
    });
  }, 3000);

  return () => clearInterval(interval);
}, []);

What I want to achieve is

-> Animation Starts

-> Progress = 1

-> Progress = 2

-> Progress = 3

-> Progress = 4

-> Progress = 5

-> Progress = 1

-> Progress = 2

and this goes on infinitely.

Is there any way to implement it without using Web APIs like setInterval and maybe using withRepeat.

1

There are 1 best solutions below

7
VonC On BEST ANSWER

You should be able to use a combination of:

  • withRepeat, a Reanimated function that repeats an animation a specified number of times or infinitely: in your case, using -1, infinitely.
  • withSequence, another Reanimated function that runs the provided animations in a sequence: in your case, from 1 to 5.

That would be (from the discussion):

const SomeThreshold = 5;

const Example = () => {
  const progress = useSharedValue(0);

  useEffect(() => {
    progress.value = withRepeat(
      withSequence(
        withTiming(0), 
        ...Array(SomeThreshold)
          .fill(0)
          .map((_, i) => withTiming(i + 1, {duration: 2000 })),
      ),
      -1,
    );
  }, []);

// ...
};

The idea is to use Array(SomeThreshold).fill(0).map((_, i) => withTiming(i + 1, {duration: 3000})) to create an array of withTiming animations that will update the progress value from 1 to SomeThreshold, with each update taking 3 seconds.

The .map((_, i) => withTiming(i + 1, {duration: 3000})) part maps over the array and for each element creates a withTiming animation that updates the progress value to i + 1.

Combined with withRepeat(withSequence(...), -1), that would repeat infinitely.

withSequence takes in 2 parameters:

  • First: an animation.
  • Second: an array (iterable) of animations.