lang/dart

Flutter Animation

C/H 2020. 9. 21. 09:30

Flutter Animation

Source Structor

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'src/app.dart';

void main() {
  // debugPaintSizeEnabled = true;

  runApp(App());
}

src/app.dart

import 'package:flutter/material.dart';
import 'screens/home.dart';

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animation',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Home(),
    );
  }
}

Flutter Animation

  • Animation
    • Records the current 'value' of the property being animated.
      애니메이션되는 속성의 현재 '값'을 기록합니다.
    • Records the status of the animation (currently running, stoppend, etc).
      애니메이션 상태 (현재 실행 중, 중지 등)를 기록합니다.
    • status: 'stopped', status: '중지됨'
      yPosition: 110px.
  • AnimationController
    • Starts, stops, restars the animation.
      애니메이션 상태 (현재 실행 중, 중지 등)를 기록합니다.
    • Records the duration of the animation.
      애니메이션의 지속 시간을 기록합니다.
    • duration: 1 second, start(), stop().
  • Tween
    • Describes the rang that the value being animated spans.
      애니메이션되는 값이 확장되는 범위를 설명합니다.
    • start with a value of 0px
      end with a value of 200px.
  • AnimatedBuilder
    • Takes an animation and a 'builder' function.
      애니메이션 및 '빌더'기능을 수행합니다.
    • Every time the animation ticks (changes value), builder reruns.
      애니메이션이 틱 (값 변경) 할 때마다 빌더가 다시 실행됩니다.

Cat Position
Rotate with Transform.rotate
Transform.rotate Roation measured in radians

src/screens/home.dart

import 'package:flutter/material.dart';
import '../widgets/cat.dart';
import 'dart:math';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> with TickerProviderStateMixin {
  Animation<double> catAnimation;
  AnimationController catController;
  Animation<double> boxAnimation;
  AnimationController boxController;

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

    boxController = AnimationController(
      duration: Duration(milliseconds: 200),
      vsync: this,
    );

    boxAnimation = Tween(
      begin: pi * 0.6,
      end: pi * 0.65,
    ).animate(
      CurvedAnimation(
        parent: boxController,
        curve: Curves.easeInOut,
      ),
    );

    boxAnimation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        boxController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        boxController.forward();
      }
    });

    catController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this, // requried with TickerProviderStateMixin
    );

    catAnimation = Tween(
      begin: -35.0,
      end: -80.0,
    ).animate(
      CurvedAnimation(
        parent: catController,
        curve: Curves.easeIn,
      ),
    );
  }

  void onTap() {
    if (catController.status == AnimationStatus.completed) {
      catController.reverse();
      boxController.forward();
    } else if (catController.status == AnimationStatus.dismissed) {
      catController.forward();
      boxController.stop();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Animation!'),
      ),
      body: GestureDetector(
        child: Center(
          child: Stack(
            overflow: Overflow.visible,
            children: [
              buildCatAnimation(),
              buildBox(),
              buildLeftFlap(),
              buildRightFlap(),
            ],
          ),
        ),
        onTap: onTap,
      ),
    );
  }

  Widget buildCatAnimation() {
    return AnimatedBuilder(
      animation: catAnimation,
      builder: (context, child) {
        return Positioned(
          child: child,
          top: catAnimation.value,
          right: 0.0,
          left: 0.0,
        );
      },
      child: Cat(),
    );
  }

  Widget buildBox() {
    return Container(
      height: 200.0,
      width: 200.0,
      color: Colors.brown,
    );
  }

  buildLeftFlap() {
    return Positioned(
      left: 3.0,
      child: AnimatedBuilder(
        animation: boxAnimation,
        child: Container(
          height: 10.0,
          width: 125.0,
          color: Colors.brown,
        ),
        builder: (context, child) {
          return Transform.rotate(
            child: child,
            alignment: Alignment.topLeft,
            angle: boxAnimation.value,
          );
        },
      ),
    );
  }

  buildRightFlap() {
    return Positioned(
      right: 3.0,
      child: AnimatedBuilder(
        animation: boxAnimation,
        child: Container(
          height: 10.0,
          width: 125.0,
          color: Colors.brown,
        ),
        builder: (context, child) {
          return Transform.rotate(
            child: child,
            alignment: Alignment.topRight,
            angle: -boxAnimation.value,
          );
        },
      ),
    );
  }
}

src/widgets/cat.dart

import 'package:flutter/material.dart';

class Cat extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Image.network('https://i.imgur.com/QwhZRyL.png');
  }
}
반응형