Longshao: the last Align play fantastic. Now there is a requirement to animate a component with some function image. You said we should go find a brick and talk to the designer.

1 2

Jet: Take it easy. We’re all adults. It’s not a big deal. I’m here. Long Shao: Have any good idea. Jet: Align. Longshao: God TM and Align, can let you water two articles, so fierce? Jet: Of course Animation is also the main point of this paper


Code implementation

Jet sputters in three minutes: achieved the sin motion, since the encapsulation of the dragon shao: Shaolin please stay, this is your article well, I am called by the director to make sauce.

Jet: I don’t even want to be lazy.

class MathRunner extends StatefulWidget { MathRunner({ Key key, }) : super(key: key); @override _MathRunnerState createState() => _MathRunnerState(); } class _MathRunnerState extends State<MathRunner> with SingleTickerProviderStateMixin { AnimationController _controller; Animation animationX; Double _x = 1.0; double _y = 0; @override void initState() { _controller = AnimationController(vsync: this, duration: Duration(seconds: 3)); AnimationX = Tween(begin: -1.0, end: 1.0).animate(_controller).. addListener(() { setState(() { _x = animationX.value; _y = f(_x); }); }); super.initState(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { _controller.repeat(reverse: true); }, child: Container( width: 300, color: Colors.grey.withAlpha(33), height: 150, child: Align( alignment: Alignment(_x, _y), child: CircleAvatar( backgroundImage: AssetImage("images/icon_head.png"), ), ), ), ); } double f(double x) { double y = sin(pi * x); return y; }}Copy the code
Implementation approach

Jet: Use an AnimationController as an animator between 0 and 1, and then use Tween to buff the AnimationController so that it moves between -1 and 1 and becomes animationX.

The magic of Align is now just _y = f(_x); Dynamically modify the location.


Simple packaging
typedef FunNum1=Function(double t ); class MathRunner extends StatefulWidget { MathRunner({Key key, this.child, this.f, this.g,this.reverse=true}) : super(key: key); final Widget child; final FunNum1 f; final FunNum1 g; final bool reverse; @override _MathRunnerState createState() => _MathRunnerState(); } class _MathRunnerState extends State<MathRunner> with SingleTickerProviderStateMixin { AnimationController _controller; Animation animationX; Double _x = 1.0; double _y = 0; @override void initState() { _controller = AnimationController(vsync: this, duration: Duration(seconds: 3)); AnimationX = Tween(begin: -1.0, end: 1.0).animate(_controller).. addListener(() { setState(() { _x = widget.f(animationX.value); _y = widget.g(animationX.value); }); }); super.initState(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { _controller.repeat(reverse: widget.reverse); }, child: Container( child: Align( alignment: Alignment(_x, _y), child: widget.child, ), ), ); }}Copy the code

Jet: Sine motion, easy

Container(
    width: 150,
    height: 150,
    child: MathRunner(
        f: (t)=>t,
        g: (t)=>sin(t*pi),
        child:CircleAvatar(
        backgroundImage: AssetImage("images/icon_head.png"),
        )));
Copy the code

Jet: Round and round, go

    var circle=Container(
        width: 150,
        height: 150,
        child: MathRunner(
          reverse: false,
          f: (t)=>cos(t*pi),
          g: (t)=>sin(t*pi),
          child: CircleAvatar(
            backgroundImage: AssetImage("images/icon_head.png"),
          ),
        ));
Copy the code

Elliptic motion: So easy (here are four inclined ellipses around)

Container( width: 150, height: 150, child: MathRunner( reverse: false, f: (t)=>cos(t*pi), g: (t)=>0.6*sin(t* PI), child:CircleAvatar(backgroundImage: AssetImage("images/icon_head.png"),));Copy the code

Pure Cartesian heart line, take it:

var love=Container(
    width: 100,
    height: 100,
    child: MathRunner(
        reverse: false,
        f: (t)=>1*(2*cos(t*pi)-cos(2*t*pi)),
        g: (t)=>1*(2*sin(t*pi)-sin(2*t*pi)),
        child:Ball(color: Colors.red,)));
Copy the code

Longshao: in fact, this requirement was not raised by design, but I wanted to make a heart-shaped thread for Wu Ying

Longshao: Yesterday I went from grade one to grade six in math. I feel like I’ve learned something new from the past, and I think it’s totally different when I look at it from today’s perspective. By the time I finish junior high math today, I should be as good as you.

Jet: TSK, TSK, although not beyond junior high school math so far. Well, I guess you’re underestimating me by not letting you experience the horrors of discrete mathematics.


This is the end of this article. If you want to taste Flutter quickly, Flutter For Seven days is a must-have. If you want to explore it, follow in my footsteps and complete a Flutter tour. In addition, I have a Flutter wechat communication group. You are welcome to join and discuss Flutter issues together. My wechat account is ZDL1994328.

Full of absurd words, a bitter tears. All the authors are crazy, who solve the taste.