Xmas!送你Flutter Animation小星星!

Posted 码个蛋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Xmas!送你Flutter Animation小星星!相关的知识,希望对你有一定的参考价值。


博客:https://juejin.im/post/5c176700f265da61602cd6ff


Dear buddy, 

Xmas!


Flutter已经出了一段时间了,你有没有了解体验过?

越来越多的新框架,新技术,有没有觉得来不及学那么多,还愿意接触新事物吗?


别的不多说,来看一下Flutter做的动画效果,就当作Xmas的烟花吧!


镇楼图!


星扩动


Xmas!送你Flutter Animation小星星!


一. 入门级动画:五角星的长大


Xmas!送你Flutter Animation小星星!


1. 照葫芦画瓢


按照昨天的Flutter初始项目,我们来自己写一个。


本人是喜欢分包的, Javaer的优良习惯。至少逻辑清晰,分工明确,我创建了一个pager包。


主页面内容用AnimaPage,虽然暂时还不知道StatefulWidget是什么,反正按照套路出牌就行了。


仿照初始项目的套路写,这里绘图区自定义AnimaView,打算对五角星的外接圆半径R进行动画。


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toly/view/anima_view.dart';

class AnimaPage extends StatefulWidget {
 @override
 _AnimaPageState createState() => _AnimaPageState();
}

class _AnimaPageState extends State<AnimaPage>{
 double _R = 25;//五角星的外接圆半径

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text("张风捷特烈"),
     ),
     body: CustomPaint(
       painter: AnimaView(context, _R),
     ),
     floatingActionButton: FloatingActionButton(
       onPressed: () {
       },
       tooltip: 'Increment',
       child: Icon(Icons.add),
     ),
   );
 }
}


2. AnimaView的实现


n角星的路径第一天已经封装好了,不会的可以去看一下


import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toly/helper/common_path.dart';
import 'package:toly/helper/help_view.dart';

class AnimaView extends CustomPainter {
 Paint mPaint;
 BuildContext context;
 double _R;

 AnimaView(this.context, double r) {
   mPaint = new Paint();
   mPaint.color = Colors.deepOrange;
   _R = r;
 }

 @override
 void paint(Canvas canvas, Size size) {
   var winSize = MediaQuery.of(context).size;
   drawGrid(canvas, winSize);
   drawCoo(canvas, new Size(160, 320), winSize);
   canvas.translate(160, 320);
   canvas.drawPath(nStarPath(5, _R, 50), mPaint);
 }
 @override
 bool shouldRepaint(CustomPainter oldDelegate) {
   return true;
 }
}


3. 让数据动起来


现在万事俱备,只欠东风把R的值吹动就行了,下面有请Animation登场!


vsync:

需要 with SingleTickerProviderStateMixi;


Tween:

补间动画----这里即:在 25.0, ~ 150.0之间在2000ms之内均匀变化

 (PS:由于程序运行情况不同,并非绝对均匀,但整体上是均匀的)

..:

是级联运算,相当于再使用此对象,这里..也就代表animation.


class AnimaPage extends StatefulWidget {
 @override
 _AnimaPageState createState() => _AnimaPageState();
}

class _AnimaPageState extends State<AnimaPage>
   with SingleTickerProviderStateMixin
{
 AnimationController controller;
 Animation<double> animation;
 double _R = 25;

 @override
 void initState() {
   super.initState();
   // 创建 AnimationController 对象
   //|----vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源
   controller = AnimationController(
       duration: const Duration(milliseconds: 2000), vsync: this);
   animation = Tween(begin: 25.0, end: 150.0).animate(controller)
     ..addListener(() {
       setState(() {
         _R = animation.value;
       });
     });
 }

 @override
 void dispose() {
   super.dispose();
   controller.dispose(); // 资源释放
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text("张风捷特烈"),
     ),
     body: CustomPaint(
       painter: AnimaView(context, _R),
     ),
     floatingActionButton: FloatingActionButton(
       onPressed: () {
         controller.forward(); //执行动画
       },
       tooltip: 'Increment',
       child: Icon(Icons.add),
     ),
   );
 }
}


这样最简单的动画就动起来了。


4. 来理一理思路


把源码翻一翻,感觉整个动画体系也不是非常复杂。


套路就是: 

Animatable用animate方法,把一个Animation包裹一下,形成一个更厉害的Animation。


至于他们的n个儿子,也就是对数据的处理不同,产生的效果不同罢了,套路知道了,一切好办。



Xmas!送你Flutter Animation小星星!


可以看出api并没有想象中的那么多,所以别怕。


Xmas!送你Flutter Animation小星星!


二. 入门级动画:五角星的绽放


前面用了补间动画Tween,而且只动了一下,下面带来连续运动的不均匀动画。



匀速往复动

Xmas!送你Flutter Animation小星星!
自定义曲线
Xmas!送你Flutter Animation小星星!
bounceInOut
Xmas!送你Flutter Animation小星星!

1. 往复运动


1.1 运动状态


你可以想象成一个人在一个范围数字跑道上跑步:


enum AnimationStatus {
 /// The animation is stopped at the beginning
 dismissed,//在正在开始时停止了
 /// The animation is running from beginning to end
 forward,//运动中
 /// The animation is running backwards, from end to beginning
 reverse,//跑到终点,再跑回来的时候
 /// The animation is stopped at the end
 completed,//跑到终点是
}


1.2 状态的监听


addStatusListener: 可以监听当前运动状态: 只要让它跑完了,再往回跑就行了。


animation = Tween(begin: 25.0, end: 150.0).animate(controller)
     ..addListener(() {
       setState(() {
         _R = animation.value;
       });
     })
     ..addStatusListener((status) {
       if (status == AnimationStatus.completed) {
         controller.reverse();
       } else if (status == AnimationStatus.dismissed) {
         controller.forward();
       }
     });


2. 变速跑

就像运动员变速跑一样,感觉就像游戏里加buff, 本来是匀速的Animation。

给价格变速的buff就变速起来了,加buff的类就是Animatable, 它的子类有一个CurveTween:


animation = Tween(begin: 25.0, end: 150.0).animate(
       CurveTween(curve: Curves.bounceInOut).animate(controller))


就这么简单,Curves里有几个内置的变速器,给原来的animation装上就行了。


Xmas!送你Flutter Animation小星星!


3. 自定义变速曲线


3.1 追踪一下源码


---->[CurveTween]---------控件只有一参Curve------------------------
class CurveTween extends Animatable<double> {
 /// Creates a curve tween.
 ///
 /// The [curve] argument must not be null.
 CurveTween({ @required this.curve })
   : assert(curve != null);

 /// The curve to use when transforming the value of the animation.
 Curve curve;
 
---->[Curve]--------抽象的,找儿子去--------------------
@immutable
abstract class Curve {

---->[Curve]--------四参构造的曲线,整合我意--------------------
class Cubic extends Curve {
 /// Creates a cubic curve.
 ///
 /// Rather than creating a new instance, consider using one of the common
 /// cubic curves in [Curves].
 ///
 /// The [a], [b], [c], and [d] arguments must not be null.
 const Cubic(this.a, this.b, this.c, this.d)


3.2 Chrome小工具


作为一名前端业余爱好者,Chrome里有个小东西很有用,曲线生成,自带预览,简直无心插柳柳成荫。(记得掘金的头像可以转,有translate属性)


Xmas!送你Flutter Animation小星星!


Xmas!送你Flutter Animation小星星!


3.3 使用


animation = Tween(begin: 25.0, end: 150.0).animate(
       CurveTween(curve: Cubic(0.96, 0.13, 0.1, 1.2)).animate(controller))


Xmas!送你Flutter Animation小星星!


Ok, 基本上就这样,你get了吗?


三. 初级动画:太阳的诞生


红太阳 星与阳
Xmas!送你Flutter Animation小星星!
Xmas!送你Flutter Animation小星星!

1. 红太阳:整型int 动画

套路学会了,这些动态改变一下n角星的尖角数,看看效果


1.1 AnimaPage里定义尖角数动画


Xmas!送你Flutter Animation小星星!


1.2 AnimaView增加入参


Xmas!送你Flutter Animation小星星!

2. 星与阳:颜色动画

ColorTween相当于添加颜色改变的buff,入参的自己加吧,和上面一样,给画笔填色就行了


Xmas!送你Flutter Animation小星星!


3. 其他效果

自己玩玩吧,随便改些属性


星扩动


Xmas!送你Flutter Animation小星星!


星扩动:  五角星内接圆半径为外接圆一半,外接圆半径变大,角数变多,颜色变红。



这篇主要是为了把Flutter动画小星星送给你!


下一次,会给大家看好玩的粒子运动!


以上~


Wish U Merry Christmas!



与内容相关联文章:




Xmas!送你Flutter Animation小星星!


等等,先别走!「码个蛋」又有活动了!参与活动不但可以培养自己的好习惯,还能拿到「码个蛋」IP系列专属奖品,速度要快...

Xmas!送你Flutter Animation小星星!   


Xmas!送你Flutter Animation小星星!


Xmas!送你Flutter Animation小星星!


今日问题:

你体验过Flutter哪些技能了吗?


留言格式:

打卡 x 天,答:xxx


Xmas!送你Flutter Animation小星星!


告诉你一个小技巧:

只需3步,你将不会错过任何一篇文章!




以上是关于Xmas!送你Flutter Animation小星星!的主要内容,如果未能解决你的问题,请参考以下文章

Flutter: Animation - 如何制作动画列表?

Flutter - AnimatedBuilder ,第一次加载时出现动画/小部件错误

Flutter 之 动画1

Flutter:如何将 PageRoute Animation 与 Navigator.of(context).pushNamed 结合起来

flutter-动画

HTML Animation 前端就业课 第二阶段CSS 零基础到实战(06)