最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Reanimated v2 - Synchronised shared values - Stack Overflow

programmeradmin4浏览0评论

Question

I'm trying to create this animation using Reanimated v2:

This is the current implementation:

const opacity1 = useSharedValue(0);
const opacity2 = useSharedValue(0);
const opacity3 = useSharedValue(0);
useEffect(() => {
  const duration = 600;
  const timingOptions = { duration: duration };
  const pulse = withTiming(1, timingOptions);
  const repeated = withRepeat(pulse, -1, true);
  opacity1.value = repeated;
  // *
  opacity2.value = withDelay(duration / 2, repeated);
  // *
  opacity3.value = withDelay(duration, repeated);
}, []);

The problem is that where I've marked the code with // * there seem to be some random delay (probably due to the JS execution) that cause the three dots to sometimes end up in sync (having the same opacity).

I presume the problem is that updating those 3 values is not atomic, so anything can happen in between those assignments.

What's the best way to solve this and have those 3 shared values with a deterministic delay between each other?


What have I tried?

  • I tried using 1 useSharedValue and 2 useDerivedValues but the math to get one to start at 0, one to start at 0.5, and one to start at 1 is non trivial (just adding 0.5 between each other and moduling it (%) to 1 doesn't account for the withRepeat going back after reaching 1)
  • I tried using a useSharedValue([0, 0, 0]) and then updating it with an atomic operation, but that doesn't seem to be supported

Question

I'm trying to create this animation using Reanimated v2:

This is the current implementation:

const opacity1 = useSharedValue(0);
const opacity2 = useSharedValue(0);
const opacity3 = useSharedValue(0);
useEffect(() => {
  const duration = 600;
  const timingOptions = { duration: duration };
  const pulse = withTiming(1, timingOptions);
  const repeated = withRepeat(pulse, -1, true);
  opacity1.value = repeated;
  // *
  opacity2.value = withDelay(duration / 2, repeated);
  // *
  opacity3.value = withDelay(duration, repeated);
}, []);

The problem is that where I've marked the code with // * there seem to be some random delay (probably due to the JS execution) that cause the three dots to sometimes end up in sync (having the same opacity).

I presume the problem is that updating those 3 values is not atomic, so anything can happen in between those assignments.

What's the best way to solve this and have those 3 shared values with a deterministic delay between each other?


What have I tried?

  • I tried using 1 useSharedValue and 2 useDerivedValues but the math to get one to start at 0, one to start at 0.5, and one to start at 1 is non trivial (just adding 0.5 between each other and moduling it (%) to 1 doesn't account for the withRepeat going back after reaching 1)
  • I tried using a useSharedValue([0, 0, 0]) and then updating it with an atomic operation, but that doesn't seem to be supported
Share Improve this question edited Dec 11, 2021 at 11:56 Shoe asked Dec 11, 2021 at 11:09 ShoeShoe 76.3k38 gold badges176 silver badges278 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 9

I've found a solution, not sure if it's the best one but it currently works.

The idea is:

  • have one shared value "progress" whose 0 -> 1 map to a plete animation cycle (e.g. 0 -> 1 -> 0)
  • have 3 derived values that start at different moments and interpolate differently:
    • one 0 -> 0.5 -> 1 -> 0.5 -> 0
    • one 0.5 -> 1 -> 0.5 -> 0 -> 0.5
    • one 1 -> 0.5 -> 0 -> 0.5 -> 1

and here's the code:

const progress = useSharedValue(0);
useEffect(() => {
  const pulse = withTiming(1, { duration: 1200, easing: Easing.linear });
  progress.value = withRepeat(pulse, -1, false);
}, []);

const opacity1 = useDerivedValue(() =>
  interpolate(progress.value, [0, 0.25, 0.5, 0.75, 1], [0, 0.5, 1, 0.5, 0])
);
const opacity2 = useDerivedValue(() =>
  interpolate(progress.value, [0, 0.25, 0.5, 0.75, 1], [0.5, 1, 0.5, 0, 0.5])
);
const opacity3 = useDerivedValue(() =>
  interpolate(progress.value, [0, 0.25, 0.5, 0.75, 1], [1, 0.5, 0, 0.5, 1])
);
发布评论

评论列表(0)

  1. 暂无评论