home

Flutterのアニメーションで四角を動かしてみる

2023-03-11T16:11:04+09:00

はじめに

 前回、Flutterのアニメーションについて学習しました。

応用として四角がかわいく(?)動くようにしました。
変化する値としては以下の4つです。

  • サイズ
  • 透明度
  • 傾き

try2.gif

コード

注意点として、ColorだけはTweenではなくColorTweenクラスをつかってTweenオブジェクトを生成するところです。

main.dart
import 'package:flutter/material.dart';
import 'dart:math';

void main() => runApp(const LogoApp());

class AnimatedLogo extends AnimatedWidget {
  const AnimatedLogo({super.key, required Animation<double> animation})
      : super(listenable: animation);

  // Make the Tweens static because they don't change.
  static final _opacityTween = Tween<double>(begin: 0.1, end: 1);
  static final _sizeTween = Tween<double>(begin: 0, end: 300);
  static final _transformTween = Tween<double>(begin: 0, end: 90);
  static final _colorTween = ColorTween(begin: Colors.grey, end: Colors.pink);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Center(
      child: Opacity(
        opacity: _opacityTween.evaluate(animation),
        child: Container(
          transform: Matrix4.rotationZ(_transformTween.evaluate(animation) * pi / 180),
          margin: const EdgeInsets.symmetric(vertical: 10),
          height: _sizeTween.evaluate(animation),
          width: _sizeTween.evaluate(animation),
          decoration: BoxDecoration(
            color: _colorTween.evaluate(animation),
            borderRadius: BorderRadius.circular(16.0),
          ),
        ),
      ),
    );
  }
}

class LogoApp extends StatefulWidget {
  const LogoApp({super.key});

  @override
  State<LogoApp> createState() => _LogoAppState();
}

class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
  late Animation<double> animation;
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          controller.reverse();
        } else if (status == AnimationStatus.dismissed) {
          controller.forward();
        }
      });
    controller.forward();
  }

  @override
  Widget build(BuildContext context) => AnimatedLogo(animation: animation);

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

自己紹介

サムネイル

y5347M

バックエンドエンジニアをしています。