animateToPage method

void animateToPage(
  1. int page, {
  2. Duration duration = const Duration(milliseconds: 300),
  3. Curves curve = Curves.easeInOut,
})

Animates smoothly to the specified page index.

Note that animation is ignored when duration is zero, and the page index is not checked to be within the range of the scroll view's pages.

Example

final controller = PageController();
controller.animateToPage(
  2,
  duration: const Duration(milliseconds: 500),
  curve: Curves.easeIn,
);

Implementation

void animateToPage(
  int page, {
  Duration duration = const Duration(milliseconds: 300),
  Curves curve = Curves.easeInOut,
}) {
  if (_attachedElement == null) return;

  final isHoriz = direction == ScrollDirection.horizontal;

  // calculate page size
  final pageSize =
      (isHoriz
          ? _attachedElement!.clientWidth
          : _attachedElement!.clientHeight) *
      viewportFraction;

  // calculate target scroll offset
  final targetOffset = page * pageSize;

  // jump immediately if duration is zero
  if (duration == Duration.zero) {
    jumpToPage(page);
    return;
  }

  // calculate starting offset and change
  final startOffset = isHoriz
      ? _attachedElement!.scrollLeft
      : _attachedElement!.scrollTop;

  // calculate change in scroll offset
  final change = targetOffset - startOffset;

  // setup animation variables
  final startTime = DateTime.now().millisecondsSinceEpoch;
  final totalDurationMs = duration.inMilliseconds;

  void step() {
    if (_attachedElement == null) return;

    // calculate animation progress
    final elapsed = DateTime.now().millisecondsSinceEpoch - startTime;
    final progress = (elapsed / totalDurationMs).clamp(
      0.0,
      1.0,
    );

    // calculate easing progress
    final easedProgress = curve.build(progress);

    // calculate current scroll position
    final current = startOffset + change * easedProgress;

    // update scroll position
    if (isHoriz) {
      _attachedElement!.scrollLeft = current;
    } else {
      _attachedElement!.scrollTop = current;
    }

    // notify listeners of scroll position changes
    notifyListeners();

    // continue animation if not done
    if (progress < 1.0) onComponentRendered(step);
  }

  // start animation
  step();
}