How to delay an animation before the animation start and at the middle of the animation?

1,045

To achieve your desired animation, you need:

  • Chain() and ConstantTween for TweenSequenceItem
  • Interval in CurvedAnimation when animating

Something like this:

@override
  void initState() {
    super.initState();
    _animationController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 3000));
    _rotateAnimation = TweenSequence([
      TweenSequenceItem(
          tween: Tween(begin: 2 * pi, end: pi)
              .chain(CurveTween(curve: Curves.linear)),
          weight: 1),
      TweenSequenceItem<double>(tween: ConstantTween<double>(pi), weight: 1),
      TweenSequenceItem(
          tween: Tween(begin: pi, end: 0.0)
              .chain(CurveTween(curve: Curves.linear)),
          weight: 1)
    ]).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Interval(
          0.3,
          1,
          curve: Curves.linear,
        ),
      ),
    );
    _scaleAnimation = TweenSequence([
      TweenSequenceItem(
          tween: Tween(begin: 0.5, end: 1.0)
              .chain(CurveTween(curve: Curves.linear)),
          weight: 1),
      TweenSequenceItem<double>(
        tween: ConstantTween<double>(1.0),
        weight: 1,
      ),
      TweenSequenceItem(
          tween: Tween(begin: 1.0, end: 0.5)
              .chain(CurveTween(curve: Curves.linear)),
          weight: 1),
    ]).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Interval(
          0.3,
          1,
          curve: Curves.linear,
        ),
      ),
    );
    _animationController.repeat();
  }

The animation will be: enter image description here

Share:
1,045
Dung Ngo
Author by

Dung Ngo

Developer.

Updated on December 26, 2022

Comments

  • Dung Ngo
    Dung Ngo over 1 year

    I'm trying to insert a delayed time at the start and between my animation so that after the delayed time is finish, the animation continues to run normally.

    Here's the part that I have done, which is an animation with rotation and scaling. So to be specific, what I want is before the animation start rotating and scaling, it will be delayed/paused for 0.3 seconds. After that, when the animation has rotated 180 degrees and scaled up, it will then be delayed/paused again for 0.3 seconds. Then, it will finish the last 180 degrees and scale down. Then the process repeat.

    animation.dart

    import 'package:flutter/material.dart';
    import 'dart:math';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
      AnimationController _animationController;
      Animation<double> _rotateAnimation;
      Animation<double> _scaleAnimation;
    
      @override
      void initState() {
        super.initState();
        _animationController = AnimationController(
            vsync: this, duration: const Duration(milliseconds: 3000));
        _rotateAnimation = TweenSequence([
          TweenSequenceItem(tween: Tween(begin: 2*pi, end: pi), weight: 1),
          TweenSequenceItem(tween: Tween(begin: pi, end: 0.0), weight: 1)
        ]).animate(CurvedAnimation(parent: _animationController, curve: Curves.linear));
        _scaleAnimation = TweenSequence([
          TweenSequenceItem(tween: Tween(begin: 0.5, end: 1.0), weight: 1),
          TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.5), weight: 1),
        ]).animate(CurvedAnimation(parent: _animationController, curve: Curves.linear));
        _animationController.repeat();
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Container(
              height: 100,
              width: 100,
              child: AnimatedBuilder(
                animation: _animationController,
                builder: (_, child) {
                  return Transform(
                    alignment: Alignment.center,
                    transform: Matrix4.identity()
                    ..scale(_scaleAnimation.value)
                    ..rotateZ(_rotateAnimation.value),
                    child: Container(
                      color: Colors.red
                    )
                  );
                }
              )
            ),
          ),
        );
      }
    }
    

    Any help or suggestion is much appreciated. Thanks.

    • Dung Ngo
      Dung Ngo over 3 years
      okay, I didn't pay attention to the ConstantTween. I got it, thanks for your help
    • Dung Ngo
      Dung Ngo over 3 years
      One more question, how do I specify the duration for the ConstantTween?