paurakhsharma / flutter_chord

Lyrics Chord parser for Flutter
MIT License
24 stars 13 forks source link

Continuous scrolling even when user taps on screen (Documentation) #27

Open jeremiahlukus opened 10 months ago

jeremiahlukus commented 10 months ago

When playing guitar often the scroll speed is slightly too slow or fast i wanted to be able to correct the screen while its still scrolling. This took me a few hours so i figured I would share since this is a pretty common functionality in guitar applications.

https://github.com/paurakhsharma/flutter_chord/assets/17206638/9087122a-bfd1-42bf-b230-1941799e5377

...
final scrollController = ScrollController(); // pass this into LyricsRender
...

  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      ScrollDirection? lastDirection;
      scrollController.addListener(() {
        lastDirection = scrollController.position.userScrollDirection;
      });
      scrollController.position.isScrollingNotifier.addListener(() {
        //  If scrollController has stopped, and the last scroll direction
        //  was reverse (upwards), it calculates the remaining scroll extent
        // (extentToGo) and the time it should take to scroll to the end at the
        // current scrollSpeed
        if (!scrollController.position.isScrollingNotifier.value) {
          if (scrollSpeed > 0 && scrollController.hasClients && lastDirection == ScrollDirection.reverse) {
            final extentToGo = scrollController.position.maxScrollExtent - scrollController.offset;
            final seconds = (extentToGo / scrollSpeed).floor();
            try {
              // We know this will error since scrollController.hasClients is true at this point
              // To avoid Failed assertion '_hold == null || _drag == null'
              // We need to stop the scrolling by calling jumpTo with the current scroll position.
              // This will effectively stop the scrolling animation.
              // Then we start it again
              scrollController
                ..jumpTo(scrollController.offset)
                ..animateTo(
                  scrollController.position.maxScrollExtent,
                  duration: Duration(seconds: seconds),
                  curve: Curves.linear,
                );
            } catch (e) {
              Sentry.captureException(e, stackTrace: StackTrace.current);
            }
          }
        }
      });
    });
jeremiahlukus commented 10 months ago

If you wanted to see the code here is the PR https://github.com/jeremiahlukus/guitar_tabs/pull/87/files

Ill merge this to keep it simple and straightforward.

jeremiahlukus commented 10 months ago

@paurakhsharma feel free to close this I just wanted it to be searchable for the next person.