【Flutter】【packages】simple_animations 简单的实现动画

在这里插入图片描述

package:simple_animations

导入包到项目中去

  • 可以实现简单的动画,
  • 快速实现,不需要自己过多的设置
  • 有多种样式可以实现
  • [ ]

功能:

简单的用例:具体需要详细可以去 pub 链接地址

1. PlayAnimationBuilder

PlayAnimationBuilder<double>(

      tween: Tween(begin: 100.0, end: 200.0), //数值是100 到00
      duration: const Duration(seconds: 1), // 动画的时间,是1s 完成动画
      builder: (context, value, _) {
        return Container(
          width: value, // 使用tween 的数值
          height: value,
          color: Colors.blue,
        );
      },
      onCompleted: () {
        // 结束的时候做什么操作
      },
      onStarted: (){
        //在开始的时候运行什么,做什么操作
      },
    )

新增child 参数,静态的child ,减少资源的浪费,其他的build 同样可以这样使用

PlayAnimationBuilder<double>(
      tween: Tween(begin: 50.0, end: 200.0),
      duration: const Duration(seconds: 5),
      child: const Center(child: Text('Hello!')), // pass in static child
      builder: (context, value, child) {
        return Container(
          width: value,
          height: value,
          color: Colors.green,
          child: child, // use child inside the animation
        );
      },
    )

2.LoopAnimationBuilder 循环动画

该用例,是一个正方形旋转360度,并且持续的转动

Center(
      child: LoopAnimationBuilder<double>(
        tween: Tween(begin: 0.0, end: 2 * pi), // 0° to 360° (2π)
        duration: const Duration(seconds: 2), // for 2 seconds per iteration
        builder: (context, value, _) {
          return Transform.rotate(
            angle: value, // use value
            child: Container(color: Colors.blue, width: 100, height: 100),
          );
        },
      ),
    )

3.MirrorAnimationBuilder 镜像动画

        MirrorAnimationBuilder<double>(
          tween:
              Tween(begin: -100.0, end: 100.0), // x 轴的数值
          duration: const Duration(seconds: 2),//动画时间
          curve: Curves.easeInOutSine, // 动画曲线
          builder: (context, value, child) {
            return Transform.translate(
              offset: Offset(value, 0), // use animated value for x-coordinate
              child: child,
            );
          },
          child: Container(
            width: 100,
            height: 100,
            color: Colors.green,
          ),
        )

4.CustomAnimationBuilder 自定义动画,可以在stl 无状态里面使用

        CustomAnimationBuilder<double>(
          control: Control.mirror,
          tween: Tween(begin: 100.0, end: 200.0),
          duration: const Duration(seconds: 2),
          delay: const Duration(seconds: 1),//延迟1s才开始动画
          curve: Curves.easeInOut,
          startPosition: 0.5,
          animationStatusListener: (status) {
          //状态的监听,可以在这边做一些操作
            debugPrint('status updated: $status');
          },
          builder: (context, value, child) {
            return Container(
              width: value,
              height: value,
              color: Colors.blue,
              child: child,
            );
          },
          child: const Center(
              child: Text('Hello!',
                  style: TextStyle(color: Colors.white, fontSize: 24))),
        )

带控制器

        CustomAnimationBuilder<double>(
          duration: const Duration(seconds: 1),
          control: control, // bind state variable to parameter
          tween: Tween(begin: -100.0, end: 100.0),
          builder: (context, value, child) {
            return Transform.translate(
              // animation that moves childs from left to right
              offset: Offset(value, 0),
              child: child,
            );
          },
          child: MaterialButton(
            // there is a button
            color: Colors.yellow,
            onPressed: () {
              setState(() {
                control = (control == Control.play)
                    ? Control.playReverse
                    : Control.play;
              });
            }, // clicking button changes animation direction
            child: const Text('Swap'),
          ),
        )

5.MovieTween 补间动画,可并行的动画

可以一个widget 多个动画同时或者不同时的运行

final MovieTween tween = MovieTween()
  ..scene(
          begin: const Duration(milliseconds: 0),
          end: const Duration(milliseconds: 1000))
      .tween('width', Tween(begin: 0.0, end: 100.0)) //0-1秒的的 width 的数值
  ..scene(
          begin: const Duration(milliseconds: 1000),
          end: const Duration(milliseconds: 1500))
      .tween('width', Tween(begin: 100.0, end: 200.0)) //1-1。5秒的的 width 的数值
  ..scene(
          begin: const Duration(milliseconds: 0),
          duration: const Duration(milliseconds: 2500))
      .tween('height', Tween(begin: 0.0, end: 200.0)) //0-2.5秒的的 height 的数值
  ..scene(
          begin: const Duration(milliseconds: 0),
          duration: const Duration(milliseconds: 3000)) //0-3 秒的的 颜色 的数值
      .tween('color', ColorTween(begin: Colors.red, end: Colors.blue));




 PlayAnimationBuilder<Movie>(
   tween: tween, // Pass in tween
   duration: tween.duration, // Obtain duration
   builder: (context, value, child) {
     return Container(
       width: value.get('width'), // Get animated values
       height: value.get('height'),
       color: value.get('color'),
     );
   },
 ),

6.MovieTween 串行的动画补间

简单的意思就是,按照设计的动画一个一个执行,按照顺序来执行,可以设置不同的数值或者是参数来获取,然后改变动画

final signaltween = MovieTween()
  ..tween('x', Tween(begin: -100.0, end: 100.0),
          duration: const Duration(seconds: 1))
      .thenTween('y', Tween(begin: -100.0, end: 100.0),
          duration: const Duration(seconds: 1))
      .thenTween('x', Tween(begin: 100.0, end: -100.0),
          duration: const Duration(seconds: 1))
      .thenTween('y', Tween(begin: 100.0, end: -100.0),
          duration: const Duration(seconds: 1));


LoopAnimationBuilder<Movie>(
  tween: signaltween,
  builder: (ctx, value, chid) {
    return Transform.translate(
        offset: Offset(value.get('x'), value.get('y')),
        child: Container(
          width: 100,
          height: 100,
          color: Colors.green,
        ));
  },
  duration: signaltween.duration,
),

总的代码:

import 'dart:math';

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

void main() {
  runApp(const MaterialApp(home: Scaffold(body: MyPage())));
}

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  Control control = Control.play; // state variable

  void toggleDirection() {
    // toggle between control instructions
    setState(() {
      control = (control == Control.play) ? Control.playReverse : Control.play;
    });
  }

  
  Widget build(BuildContext context) {
//电影样式的动画
    final MovieTween tween = MovieTween()
      ..scene(
              begin: const Duration(milliseconds: 0),
              end: const Duration(milliseconds: 1000))
          .tween('width', Tween(begin: 0.0, end: 100.0)) //0-1秒的的 width 的数值
      ..scene(
              begin: const Duration(milliseconds: 1000),
              end: const Duration(milliseconds: 1500))
          .tween('width', Tween(begin: 100.0, end: 200.0)) //1-1。5秒的的 width 的数值
      ..scene(
              begin: const Duration(milliseconds: 0),
              duration: const Duration(milliseconds: 2500))
          .tween('height', Tween(begin: 0.0, end: 200.0)) //0-2.5秒的的 height 的数值
      ..scene(
              begin: const Duration(milliseconds: 0),
              duration: const Duration(milliseconds: 3000)) //0-3 秒的的 颜色 的数值
          .tween('color', ColorTween(begin: Colors.red, end: Colors.blue));

    final signaltween = MovieTween()
      ..tween('x', Tween(begin: -100.0, end: 100.0),
              duration: const Duration(seconds: 1))
          .thenTween('y', Tween(begin: -100.0, end: 100.0),
              duration: const Duration(seconds: 1))
          .thenTween('x', Tween(begin: 100.0, end: -100.0),
              duration: const Duration(seconds: 1))
          .thenTween('y', Tween(begin: 100.0, end: -100.0),
              duration: const Duration(seconds: 1));

    return SingleChildScrollView(
      child: Column(
        children: [
          LoopAnimationBuilder<Movie>(
            tween: signaltween,
            builder: (ctx, value, chid) {
              return Transform.translate(
                  offset: Offset(value.get('x'), value.get('y')),
                  child: Container(
                    width: 100,
                    height: 100,
                    color: Colors.green,
                  ));
            },
            duration: signaltween.duration,
          ),

          PlayAnimationBuilder<Movie>(
            tween: tween, // Pass in tween
            duration: tween.duration, // Obtain duration
            builder: (context, value, child) {
              return Container(
                width: value.get('width'), // Get animated values
                height: value.get('height'),
                color: value.get('color'),
              );
            },
          ),
          PlayAnimationBuilder<double>(
            tween: Tween(begin: 100.0, end: 200.0), //数值是100 到00
            duration: const Duration(seconds: 1), // 动画的时间,是1s 完成动画
            builder: (context, value, _) {
              return Container(
                width: value, // 使用tween 的数值
                height: value,
                color: Colors.blue,
              );
            },
            onCompleted: () {
              // 结束的时候做什么操作
            },
            onStarted: () {
              //在开始的时候运行什么,做什么操作
            },
          ),
          MirrorAnimationBuilder<Color?>(
            tween:
                ColorTween(begin: Colors.red, end: Colors.blue), // 颜色的渐变 红色到蓝色
            duration: const Duration(seconds: 5), // 动画时长5秒
            builder: (context, value, _) {
              return Container(
                color: value, // 使用该数值
                width: 100,
                height: 100,
              );
            },
          ),

          //实现一个绿色箱子从左到右,从右到走
          MirrorAnimationBuilder<double>(
            tween: Tween(begin: -100.0, end: 100.0), // x 轴的数值
            duration: const Duration(seconds: 2), //动画时间
            curve: Curves.easeInOutSine, // 动画曲线
            builder: (context, value, child) {
              return Transform.translate(
                offset: Offset(value, 0), // use animated value for x-coordinate
                child: child,
              );
            },
            child: Container(
              width: 100,
              height: 100,
              color: Colors.green,
            ),
          ),
          CustomAnimationBuilder<double>(
            control: Control.mirror,
            tween: Tween(begin: 100.0, end: 200.0),
            duration: const Duration(seconds: 2),
            delay: const Duration(seconds: 1),
            curve: Curves.easeInOut,
            startPosition: 0.5,
            animationStatusListener: (status) {
              debugPrint('status updated: $status');
            },
            builder: (context, value, child) {
              return Container(
                width: value,
                height: value,
                color: Colors.blue,
                child: child,
              );
            },
            child: const Center(
                child: Text('Hello!',
                    style: TextStyle(color: Colors.white, fontSize: 24))),
          ),

          CustomAnimationBuilder<double>(
            duration: const Duration(seconds: 1),
            control: control, // bind state variable to parameter
            tween: Tween(begin: -100.0, end: 100.0),
            builder: (context, value, child) {
              return Transform.translate(
                // animation that moves childs from left to right
                offset: Offset(value, 0),
                child: child,
              );
            },
            child: MaterialButton(
              // there is a button
              color: Colors.yellow,
              onPressed: () {
                setState(() {
                  control = (control == Control.play)
                      ? Control.playReverse
                      : Control.play;
                });
              }, // clicking button changes animation direction
              child: const Text('Swap'),
            ),
          )
        ],
      ),
    );
  }
}

混合多种动画

import 'dart:math';

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

void main() {
  runApp(const MaterialApp(home: Scaffold(body: MyPage())));
}

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  Control control = Control.play; // state variable

  
  Widget build(BuildContext context) {
    final x = MovieTweenProperty<double>();
    final y = MovieTweenProperty<double>();
    final color = MovieTweenProperty<Color>();
    final tween = MovieTween()
      ..scene(
              begin: const Duration(seconds: 0),
              duration: const Duration(seconds: 1))
          .tween(x, Tween(begin: -100.0, end: 100.0),
              curve: Curves.easeInOutSine)
          .tween(color, ColorTween(begin: Colors.red, end: Colors.yellow))
      ..scene(
              begin: const Duration(seconds: 1),
              duration: const Duration(seconds: 1))
          .tween(y, Tween(begin: -100.0, end: 100.0),
              curve: Curves.easeInOutSine)
      ..scene(
              begin: const Duration(seconds: 2),
              duration: const Duration(seconds: 1))
          .tween(x, Tween(begin: 100.0, end: -100.0),
              curve: Curves.easeInOutSine)
      ..scene(
              begin: const Duration(seconds: 1),
              end: const Duration(seconds: 3))
          .tween(color, ColorTween(begin: Colors.yellow, end: Colors.blue))
      ..scene(
              begin: const Duration(seconds: 3),
              duration: const Duration(seconds: 1))
          .tween(y, Tween(begin: 100.0, end: -100.0),
              curve: Curves.easeInOutSine)
          .tween(color, ColorTween(begin: Colors.blue, end: Colors.red));

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: LoopAnimationBuilder<Movie>(
            tween: tween, // Pass in tween
            duration: tween.duration, // Obtain duration
            builder: (context, value, child) {
              return Transform.translate(
                // Get animated offset
                offset: Offset(x.from(value), y.from(value)),
                child: Container(
                  width: 100,
                  height: 100,
                  color: color.from(value), // Get animated color
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

边运动便改变颜色

同原生的动画混合开发

以下代码实现,一个container 的宽高的尺寸变化

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> with AnimationMixin {
  //同原生的混合使用
  // Control control = Control.play; // state variable
  late Animation<double> size;

  
  void initState() {
    super.initState();
    // controller 不需要重新定义,AnimationMixin 里面已经自动定义了个
    size = Tween(begin: 0.0, end: 200.0).animate(controller);
    controller.play(); //运行
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: Container(
            width: size.value,
            height: size.value,
            color: Colors.red,
          ),
        ),
      ),
    );
  }
}

实现图

多个控制器控制一个widget的实现多维度的动画实现

import 'dart:math';

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

void main() {
  runApp(const MaterialApp(home: Scaffold(body: MyPage())));
}

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> with AnimationMixin {
  //同原生的混合使用

  late AnimationController widthcontrol; //宽度控制
  late AnimationController heigthcontrol; //高度控制器
  late AnimationController colorcontrol; //颜色控制器

  late Animation<double> width; //宽度控制
  late Animation<double> heigth; //高度控制
  late Animation<Color?> color; //颜色控制

  
  void initState() {
// mirror 镜像
    widthcontrol = createController()
      ..mirror(duration: const Duration(seconds: 5));
    heigthcontrol = createController()
      ..mirror(duration: const Duration(seconds: 3));
    colorcontrol = createController()
      ..mirror(duration: const Duration(milliseconds: 1500));

    width = Tween(begin: 100.0, end: 200.0).animate(widthcontrol);
    heigth = Tween(begin: 100.0, end: 200.0).animate(heigthcontrol);
    color = ColorTween(begin: Colors.green, end: Colors.black)
        .animate(colorcontrol);

    super.initState();
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: Container(
            width: width.value,
            height: heigth.value,
            color: color.value,
          ),
        ),
      ),
    );
  }
}

在这里插入图片描述