How to make ColorTween animation with multiple colors in flutter

Viewed 1698

I built this custom card (from UNO game) which looks something like UNO 4+ game card

I have used a ColorTween to change the boxshadow property of a container over 1 second, with the following code

class SpecialUnoCard extends StatefulWidget {
  final String _value;
  SpecialUnoCard(this._value);

  @override
  _SpecialUnoCardState createState() => _SpecialUnoCardState();
}

class _SpecialUnoCardState extends State<SpecialUnoCard>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation _animation;
  int index = 0;

  final _listOfTweens = [
    ColorTween(begin: red, end: blue),
    ColorTween(begin: red, end: green),
    ColorTween(begin: red, end: orange),
    ColorTween(begin: blue, end: red),
    ColorTween(begin: blue, end: green),
    ColorTween(begin: blue, end: orange),
    ColorTween(begin: green, end: red),
    ColorTween(begin: green, end: blue),
    ColorTween(begin: green, end: orange),
    ColorTween(begin: orange, end: red),
    ColorTween(begin: orange, end: green),
    ColorTween(begin: orange, end: blue),
  ];

  ColorTween tween() =>
      _listOfTweens[Random().nextInt(_listOfTweens.length - 1)];

  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animation = tween()
        .chain(CurveTween(curve: Curves.easeInOutCubic))
        .animate(_controller);

    _controller.addListener(() {
      setState(() {});
    });

    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controller.forward();
      }
    });

    _controller.forward();

    super.initState();
  }

  @override
  void deactivate() {
    _controller.dispose();
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(
          vertical: _cardMarginVer, horizontal: _cardMarginHor),
      padding: EdgeInsets.all(15),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(_cardCornerRadii),
        border: Border.all(
            color: _animation.value, width: 4, style: BorderStyle.solid),
        boxShadow: [
          BoxShadow(color: _animation.value, spreadRadius: 12, blurRadius: 25)
        ],
        color: Colors.black,
      ),
      child: Container(
        height: _cardHeight,
        width: _cardWidth,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(30),
          color: Colors.black,
        ),
        child: (widget._value == plus4)
            ? SvgPicture.asset('assets/plus4.svg')
            : SvgPicture.asset('assets/wild.svg'),
      ),
    );
  }
}

Now, is there a way to animate or shuffle the colors between a bunch of values ? I want some functionality that relates to the following pseudo code

ColorTween(values: <Color>[Colors.orange , Colors.red , Colors.blue , ........]

You could say that I want to chain colors together

I have tried looking up the following post, but did not find what I needed. How could I change ColorTween colors in Flutter

Thanks for your time!

2 Answers

Try RainbowColor which allows interpolation/tweening among several colors. It provides a multi-color variant of ColorTween exactly as you describe:

RainbowColorTween([Colors.orange, Colors.red, Colors.blue])

It can also be used outside of tween context to interpolate colors across a spectrum, e.g.

var rb = Rainbow(spectrum: [Colors.orange, Colors.red, Colors.blue]);
Color warmColor = rb[0.25];
Color coldColor = rb[0.83];

Btw, good timing. I released RainbowColor just yesterday, and I honestly had no idea you asked this question a few days ago when I made it.

Check out the AnimatedContainer at https://flutter.dev/docs/cookbook/animation/animated-container. It's an easier way to handle animations and I think it has exactly what you're looking for. The test code on the page will let you test it immediately. Just put your decoration and integrate the random values a bit to see the magic. Good luck!

Related