question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

dynamic snap points cause flickering of backdrop

See original GitHub issue

https://user-images.githubusercontent.com/6340397/117680607-9ca02200-b1b1-11eb-851b-f30ab92622b6.mp4

Bug

I added a backdrop to the “Dynamic Snap Point” example and experienced flickering of the backdrop when:

  • bottom sheet is mounted
  • content height is increased

Please see the attached screen recording.

The flickering is caused by the opacity of the backdrop which is derived from animatedIndex:

https://github.com/gorhom/react-native-bottom-sheet/blob/b5a6c659e2fd4a8ead5857d3f22c55c47f4fd82e/src/components/bottomSheetBackdrop/BottomSheetBackdrop.tsx#L77-L81

When the bottom sheet is mounted, contentHeight is set to 0 and thus the animatedIndex is calculated as 1. This initializes the backdrop with its target opacity.

When contentHeight is updated in handleOnLayout and thus the snap points change, animatedIndex drops to a value below 1 and then reaches 1. This causes a change in the backdrop’s opacity which looks like it’s flickering.

LOG  animatedIndex 1
LOG  animatedIndex 0.303923371864135
LOG  animatedIndex 0.44752361701454846
LOG  animatedIndex 0.5614992061630881
LOG  animatedIndex 0.6519616911085544
LOG  animatedIndex 0.7237618123876004
LOG  animatedIndex 0.7807496059801955
LOG  animatedIndex 0.8259808478549384
LOG  animatedIndex 0.8618809080198362
LOG  animatedIndex 0.8903748046205889
LOG  animatedIndex 0.9129904250777997
LOG  animatedIndex 0.9309404549799996
LOG  animatedIndex 0.9451874030349574
LOG  animatedIndex 0.9564952131859606
LOG  animatedIndex 0.9654702279750407
LOG  animatedIndex 0.9725937019024556
LOG  animatedIndex 0.9782476068805629
LOG  animatedIndex 0.9827351142300406
LOG  animatedIndex 0.9862968511437163
LOG  animatedIndex 0.9891238036020468
LOG  animatedIndex 0.9913675572291475
LOG  animatedIndex 0.993148425662441
LOG  animatedIndex 0.994561901872919
LOG  animatedIndex 0.9956837786752039
LOG  animatedIndex 0.9965742128821735
LOG  animatedIndex 0.9972809509724073
LOG  animatedIndex 0.9978418893679171
LOG  animatedIndex 0.9982871064637325
LOG  animatedIndex 0.9986404755064244
LOG  animatedIndex 0.9989209446991162
LOG  animatedIndex 1

When contentHeight is increased, the same behavior is shown:

LOG  animatedIndex 1
LOG  animatedIndex 0.8632851491723874
LOG  animatedIndex 0.891489351466483
LOG  animatedIndex 0.9138750416347815
LOG  animatedIndex 0.9316425755464124
LOG  animatedIndex 0.9457446764953674
LOG  animatedIndex 0.9569375213867082
LOG  animatedIndex 0.9658212882250738
LOG  animatedIndex 0.9728723386287468
LOG  animatedIndex 0.978468760995804
LOG  animatedIndex 0.9829106443525916
LOG  animatedIndex 0.9864361694936971
LOG  animatedIndex 0.9892343806491268
LOG  animatedIndex 0.9914553222963229
LOG  animatedIndex 0.9932180848477181
LOG  animatedIndex 0.9946171903957283
LOG  animatedIndex 0.9957276612081754
LOG  animatedIndex 0.9966090424686902
LOG  animatedIndex 0.9973085952378943
LOG  animatedIndex 0.9978638306340945
LOG  animatedIndex 0.9983045212581616
LOG  animatedIndex 0.9986542976367383
LOG  animatedIndex 0.998931915331168
LOG  animatedIndex 0.9991522606409889
LOG  animatedIndex 0.9993271488278208
LOG  animatedIndex 0.9994659576730858
LOG  animatedIndex 0.9995761303260984
LOG  animatedIndex 0.9996635744186362
LOG  animatedIndex 0.9997329788402937
LOG  animatedIndex 0.9997880651662013
LOG  animatedIndex 0.999831787211542
LOG  animatedIndex 1 

When contentHeight is decreased, animatedIndex stays at 1 and no flickering occurs:

 LOG  animatedIndex 1
 LOG  animatedIndex 1

Environment info

Library Version
@gorhom/bottom-sheet 3.6.4
react-native 0.64.0
react-native-reanimated 2.1.0
react-native-gesture-handler 1.9.0

Steps To Reproduce

  1. set backdropComponent={BottomSheetBackdrop}
  2. modify snap points dynamically
  3. backdrop flickers

Describe what you expected to happen:

no flickering of backdrop

Ideally, animatedIndex would not change when the snap points are modified as done here. Maybe when the number of snap points stay the same, animatedIndex should stay constant?

Reproducible sample code

I modified the example app by adding the backdrop to the dynamic snap point example, please have a look: https://github.com/schiller-manuel/react-native-bottom-sheet/commit/86b628ec8c3a7f462346ecfadc461c85adcd0bbb

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
benjamin-sweneycommented, May 25, 2021

The below component will prevent the flicker on mount. It is by no means foolproof but works for a single snap point use case.

import React, { FunctionComponent } from 'react';
import { BottomSheetBackdrop, BottomSheetBackdropProps } from '@gorhom/bottom-sheet';
import { useAnimatedReaction, useSharedValue, withTiming } from 'react-native-reanimated';

import { OPEN_ANIMATION_DURATION } from './constants';

const AntiFlickerBottomSheetBackdrop: FunctionComponent<BottomSheetBackdropProps> = ({ animatedIndex, ...rest }) => {
  const adjustedAnimatedIndex = useSharedValue(0);
  const hasOpened = useSharedValue(false);

  useAnimatedReaction(() => animatedIndex.value, (data, prev) => {
    if (prev == null) {
      adjustedAnimatedIndex.value = withTiming(1, { duration: OPEN_ANIMATION_DURATION }, (isFinished) => {
        if (isFinished) hasOpened.value = true;
      });
    }

    if (hasOpened.value) adjustedAnimatedIndex.value = data;
  });

  return <BottomSheetBackdrop animatedIndex={adjustedAnimatedIndex} {...rest} />;
};

export default AntiFlickerBottomSheetBackdrop;

Ensure you also use the below animation config on the bottom sheet itself to align the timing.

const animationConfigs = useBottomSheetTimingConfigs({
  duration: OPEN_ANIMATION_DURATION,
});
3reactions
ozasadnyycommented, Jul 14, 2021

FYI: still happening on v4

Read more comments on GitHub >

github_iconTop Results From Across the Web

Well-controlled scrolling with CSS Scroll Snap - web.dev
The CSS Scroll Snap feature allows web developers to create well-controlled scroll experiences by declaring scroll snapping positions.
Read more >
Difference between types of stills and flickering - VEGAS Community
I just made a snap shot and then stretched them to my desired length. Looking at them gives you a headache. The stills...
Read more >
Drawing window flickers, flashes, or jumps as layout tabs and ...
The drawing window or command line constantly flickers black, flashes, bounces, ... It may cause difficulty in selecting Object Snaps.
Read more >
Props | React Native Bottom Sheet - GitHub Pages
Content height helps dynamic snap points calculation. type, default, required. number | Animated.SharedValue<number>, undefined, NO. containerOffset ​.
Read more >
Tilemap has tearing between tiles, even with pixel snap
I got these black lines, mostly vertically every time when my camera movement was smoothing/damping out (using CineMachine). What almost ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found