如何链接多个动画对象?

时间:2019-09-24 11:08:15

标签: flutter dart

我想要的是链接多个Animation对象,例如,如果我们有一个Animation<double>从0到40(我们称之为大对象),而我又有4个Animation<double>反对我想要的是

  1. 当大型动画开始时,第一个动画从其开始,但是直到大型动画到达10时结束。
  2. 当大个数达到20时,第二个动画开始并结束于大个数达到20时。 等等...

任何人都知道该如何做?

1 个答案:

答案 0 :(得分:1)

听起来像是交错的动画。 基本上,您可以创建一个动画控制器并设置总持续时间。 然后,您可以为要执行的每个动画创建一个单独的补间。对于每个补间,您可以定义一条曲线,对于该曲线,可以定义一个间隔,以动画总持续时间的百分比表示。当您搜索交错动画时,在flutter.dev中有一个很好的例子。注意:尽管名称如此,它们不一定要一个接一个地被发射,它们可以同时发射,但是可以根据需要结束并在不同的时间发射。我不确定仅通过共享flutter文档的链接来给出答案是否合适,但是在这里 https://flutter.dev/docs/development/ui/animations/staggered-animations。 我做了类似的事情,但是有两个控制器,我可以同时触发,但是它们的持续时间不同。

啊,我排第二:)

编辑:这是一些代码 一个带有2个控制器

import 'package:flutter/material.dart';
//import 'package:flutter/scheduler.dart';
import 'package:flutter_color_picker/components/color_ripple.dart';

class ColorKnob extends StatefulWidget {
  const ColorKnob({this.color, this.ratio, this.saveColor});

  final Color color;
  final double ratio;
  final Function saveColor;

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

class _ColorKnobState extends State<ColorKnob> with TickerProviderStateMixin {
  AnimationController scaleAnimationController;
  AnimationController rippleAnimationController;
  Animation<double> scaleAnimation;

  @override
  void initState() {
    super.initState();
    scaleAnimationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 100));

    rippleAnimationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 400));

    scaleAnimationController.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed) {
        scaleAnimationController.reverse();
      }
    });

    scaleAnimation = Tween<double>(begin: 1.0, end: 0.8).animate(
        CurvedAnimation(
            parent: scaleAnimationController, curve: Curves.easeOut));

    rippleAnimationController.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed) {
        widget.saveColor();
      }
    });

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

  @override
  void dispose() {
    super.dispose();
    scaleAnimationController.dispose();
    rippleAnimationController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
          decoration: const BoxDecoration(
              shape: BoxShape.circle, color: Colors.transparent),
          child: FractionallySizedBox(
            widthFactor: widget.ratio,
            heightFactor: widget.ratio,
            child: ClipOval(
              clipBehavior: Clip.antiAlias,
              child: Center(
                child: Stack(children: <Widget>[
                  ColorRipple(
                      controller: rippleAnimationController,
                      color: widget.color,
                  ),
                  GestureDetector(
                    onTap: () {
                      //            timeDilation = 1.0;
                      scaleAnimationController.forward(from: 0.0);
                      rippleAnimationController.forward(from: 0.0);
                    },
                    child: Transform.scale(
                      scale: scaleAnimation.value,
                      alignment: Alignment.center,
                      child: Container(
                        width: 60.0,
                        height: 60.0,
                        decoration: BoxDecoration(
                            shape: BoxShape.circle,
                            color: widget.color,
                            border: Border.all(
                              color: const Color(0xFFFFFFFF),
                              style: BorderStyle.solid,
                              width: 4.0,
                            ),
                            boxShadow: const <BoxShadow>[
                              box-shadow(
                                offset: Offset(0.0, 1.0),
                                blurRadius: 6.0,
                                spreadRadius: 1.0,
                                color: Color(0x44000000),
                              )
                            ]),
                      ),
                    ),
                  ),
                ]),
              ),
            ),
          )),
    );
  }
}

和一个带有多个补间的

import 'package:flutter/material.dart';
//import 'package:flutter/scheduler.dart';

class ColorRipple extends StatelessWidget {
  ColorRipple({this.controller, this.color, this.size})
      : scaleUpAnimation = Tween<double>(begin: 0.8, end: 5.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(
              0.2,
              1.0,
              curve: Cubic(0.25, 0.46, 0.45, 0.94),
            ),
          ),
        ),
        opacityAnimation = Tween<double>(begin: 0.6, end: 0.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(
              0.4,
              1.0,
              curve: Cubic(0.25, 0.46, 0.45, 0.94),
            ),
          ),
        ),
        scaleDownAnimation = Tween<double>(begin: 1.0, end: 0.8).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(0.0, 0.2, curve: Curves.easeOut),
          ),
        );

  final AnimationController controller;
  final Animation<double> scaleUpAnimation;
  final Animation<double> scaleDownAnimation;
  final Animation<double> opacityAnimation;
  final Color color;
  final Size size;

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: controller,
        builder: (BuildContext context, Widget child) {
          return Container(
            child: Transform(
              alignment: Alignment.center,
              transform: Matrix4.identity()
                ..scale(scaleDownAnimation.value)
                ..scale(scaleUpAnimation.value),
              child: Opacity(
                  opacity: opacityAnimation.value,
                  child: Container(
                    width: 60.0,
                    height: 60.0,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        border: Border.all(
                            color: color,
                            style: BorderStyle.solid,
                            width: 4.0 - (2 * controller.value))),
                  )),
            ),
          );
        });
  }
}