【Flutter】动画实现

2024-04-08  本文已影响0人  24c41111e47b

记录复杂的动画实现,和动画实现过程中的心得经验。


组合动画

组合动画 又叫做 交织动画, 主要用来实现多种动画效果组合在一起的复杂动画, 并且要能控制每种动画的持续时间间隔.
场景举例: 缩大+透明渐变,然后进行位移,最后再缩小+透明渐变

@override
  void initState() {
    super.initState();

    _controller = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 1800));

    // 放大:透明动画&缩放 (时长 0.3*1300)
    _blowUpAnimation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.0, 0.22, curve: Curves.ease)));

    // 位移动画
    // _animation = Tween(begin: 0.0, end: 1.0).animate(_controller);
    _animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.22, 0.8, curve: Curves.ease)));

    // 缩小:透明动画&缩放动画
    _blowDownAnimation = Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation(
        parent: _controller,
        curve: const Interval(0.82, 1.0, curve: Curves.ease)));

    _animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        // 通知外部,动画结束
        widget.completion.call();
      }
    });

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      // 开始动画
      _controller.forward();
    });
  }

... 省略无用代码
child: AnimatedBuilder(
        animation: _controller,
        builder: (ctx, child) {
          if (_controller.status == AnimationStatus.forward) {
            offset = _animationPoint(offset);
          }

          return Positioned(
            left: offset.dx,
            top: offset.dy,
            child: IgnorePointer(
              child: Opacity(
                opacity: _blowDownAnimation.value < 1.0
                    ? _blowDownAnimation.value
                    : _blowUpAnimation.value,
                child: Transform.scale(
                  scale: _blowDownAnimation.value < 1.0
                      ? _blowDownAnimation.value
                      : _blowUpAnimation.value,
                  child: Container(
                    width: 66,
                    // 宽高不能动, 如果要控制图大小,可以修改padding
                    height: 66,
                    padding: const EdgeInsets.all(10),
                    color: Colors.transparent,
                    child: CachedNetworkImage(
                      imageUrl: widget.img,
                      cacheKey: widget.img,
                      fit: BoxFit.fill,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ))
...

这里只给出了组合动画的使用方式,实际上还有很多细节没有讲解,如位移动画的位置计算等,详情可以见另外一篇文章

上一篇 下一篇

猜你喜欢

热点阅读