AnimationTimeline.cascade constructor

AnimationTimeline.cascade({
  1. required List<AnimationController> controllers,
  2. Duration hold = Duration.zero,
  3. Duration gap = Duration.zero,
  4. Duration rest = Duration.zero,
  5. bool repeat = false,
  6. bool alternate = false,
  7. Object? id,
  8. String labelBuilder(
    1. int index,
    2. String phase
    )?,
  9. void onStepStart(
    1. int index,
    2. AnimationTimelineStep step,
    3. TimelineDirection direction
    )?,
  10. void onStepComplete(
    1. int index,
    2. AnimationTimelineStep step,
    3. TimelineDirection direction
    )?,
})

Builds a serial pulse choreography across multiple controllers.

Each controller runs through:

  1. animate forward
  2. optional hold
  3. animate reverse

A gap is inserted between controllers, and an optional rest is inserted after the final controller before the next repeated cycle.

Implementation

factory AnimationTimeline.cascade({
  required List<AnimationController> controllers,
  Duration hold = Duration.zero,
  Duration gap = Duration.zero,
  Duration rest = Duration.zero,
  bool repeat = false,
  bool alternate = false,
  Object? id,
  String Function(int index, String phase)? labelBuilder,
  void Function(
    int index,
    AnimationTimelineStep step,
    TimelineDirection direction,
  )?
  onStepStart,
  void Function(
    int index,
    AnimationTimelineStep step,
    TimelineDirection direction,
  )?
  onStepComplete,
}) {
  if (controllers.isEmpty) {
    throw ArgumentError.value(
      controllers,
      'controllers',
      'must not be empty',
    );
  }

  final steps = <AnimationTimelineStep>[];
  for (var index = 0; index < controllers.length; index++) {
    final controller = controllers[index];
    steps.add(
      AnimationTimelineStep.forward(
        controller,
        label: labelBuilder?.call(index, 'in') ?? 'cascade-in-$index',
      ),
    );
    if (hold > Duration.zero) {
      steps.add(
        AnimationTimelineStep.delay(
          hold,
          label: labelBuilder?.call(index, 'hold') ?? 'cascade-hold-$index',
        ),
      );
    }
    steps.add(
      AnimationTimelineStep.reverse(
        controller,
        label: labelBuilder?.call(index, 'out') ?? 'cascade-out-$index',
      ),
    );
    if (index < controllers.length - 1 && gap > Duration.zero) {
      steps.add(
        AnimationTimelineStep.delay(
          gap,
          label: labelBuilder?.call(index, 'gap') ?? 'cascade-gap-$index',
        ),
      );
    }
  }
  if (rest > Duration.zero) {
    steps.add(
      AnimationTimelineStep.delay(
        rest,
        label:
            labelBuilder?.call(controllers.length - 1, 'rest') ??
            'cascade-rest',
      ),
    );
  }

  return AnimationTimeline(
    steps: steps,
    repeat: repeat,
    alternate: alternate,
    id: id,
    onStepStart: onStepStart,
    onStepComplete: onStepComplete,
  );
}