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

package:simple_animations

导入包到项目中去

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

功能:

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

1. PlayAnimationBuilder

dart 复制代码
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 同样可以这样使用

dart 复制代码
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度,并且持续的转动

dart 复制代码
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 镜像动画

dart 复制代码
        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 无状态里面使用

dart 复制代码
        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))),
        )

带控制器

dart 复制代码
        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 多个动画同时或者不同时的运行

dart 复制代码
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 串行的动画补间

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

dart 复制代码
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,
),

总的代码:

dart 复制代码
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);

  @override
  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;
    });
  }

  @override
  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'),
            ),
          )
        ],
      ),
    );
  }
}

混合多种动画

dart 复制代码
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);

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

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

  @override
  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 的宽高的尺寸变化

dart 复制代码
class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

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

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

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

  @override
  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的实现多维度的动画实现

dart 复制代码
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);

  @override
  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; //颜色控制

  @override
  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();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: Container(
            width: width.value,
            height: heigth.value,
            color: color.value,
          ),
        ),
      ),
    );
  }
}
相关推荐
LawrenceLan12 分钟前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
一豆羹1 小时前
macOS 环境下 ADB 无线调试连接失败、Protocol Fault 及端口占用的深度排查
flutter
行者961 小时前
OpenHarmony上Flutter粒子效果组件的深度适配与实践
flutter·交互·harmonyos·鸿蒙
行者964 小时前
Flutter与OpenHarmony深度集成:数据导出组件的实战优化与性能提升
flutter·harmonyos·鸿蒙
小雨下雨的雨4 小时前
Flutter 框架跨平台鸿蒙开发 —— Row & Column 布局之轴线控制艺术
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨4 小时前
Flutter 框架跨平台鸿蒙开发 —— Center 控件之完美居中之道
flutter·ui·华为·harmonyos·鸿蒙
小雨下雨的雨5 小时前
Flutter 框架跨平台鸿蒙开发 —— Icon 控件之图标交互美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨5 小时前
Flutter 框架跨平台鸿蒙开发 —— Placeholder 控件之布局雏形美学
flutter·ui·华为·harmonyos·鸿蒙系统
行者966 小时前
OpenHarmony Flutter弹出菜单组件深度实践:从基础到高级的完整指南
flutter·harmonyos·鸿蒙
前端不太难6 小时前
Flutter / RN / iOS,在长期维护下的性能差异本质
flutter·ios