実装したもの
背景全体を回転させます。
画面内に収まっている画像を回転させるのはかんたんでしたが、"全体"ということで画面の高さと同じ幅を持つ画像を描画する必要があり、少し面倒でした。
回転させている画像は、 https://material.io/resources/icons/?style=baseline からダウンロードしたSVG画像です。
コード
全文はこちら。
コード説明
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class RotateBackgroundScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Rotate background'),
),
body: Stack(
children: <Widget>[
_RotateBackground(),
_Screen(),
],
),
);
}
}
画面全体としては、このようになります。
Scaffold
の子要素として、"背景"Widgetと"その他画面要素"Widgetを重ねるイメージです。
class _RotateBackground extends StatefulWidget {
@override
_RotateBackgroundState createState() => _RotateBackgroundState();
}
AnimationController無しにrotateさせる方法が見当たらなかったので、StatefulWidgetとしています。
class _RotateBackgroundState extends State<_RotateBackground>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _turns;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
);
_turns = _animationController
.drive(
CurveTween(curve: Curves.linear),
)
.drive(
Tween<double>(begin: 0, end: 1),
);
_animationController.repeat();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
5秒間で1回転するアニメーションを、リピートさせています。
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
return ClipRect(
child: OverflowBox(
minWidth: 0.0,
minHeight: 0.0,
maxWidth: screenHeight,
maxHeight: screenHeight,
child: RotationTransition(
turns: _turns,
alignment: Alignment.center,
child: SvgPicture.asset(
'assets/bg.svg',
width: screenHeight,
height: screenHeight,
),
),
),
);
}
}
RotationTransition
に、先に出ていた _trans
を渡すことで、SvgPicture
が回転します。
SvgPicture
に、表示領域の高さで縦横の大きさを与えているのですが、外側の OverflowBox
を指定しない場合は、以下のように画面幅に制限されてしまいます。
さらに、その外側を ClipRect
で囲むことで、以下のように画面遷移のタイミングで変に見えてしまうことを防いでいます。
(画面の大きさを飛び越えて、SVG画像が表示されてしまっている。)
終わり
OverflowBox
や ClipRect
を利用することで、画面外に画像を描画しつつ、アニメーションで見せることができました。
これを転用して、キャラクターが横から出たり引っ込んだりするUIも作れそうですね。
「どれだけのWidgetを知っているか」で実装できる幅が変わってきそうなので、 https://www.youtube.com/playlist?list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG を流し見ておくのは大事かもしれません。