コンサルティング事業について詳しく知りたい方はこちら
前回までのおはなし
○ ヘッダー編
Flutter × UI #01 ~ agexコーポレートサイトをトレースしてみた (ヘッダー編) ~
○ スライダー編
Flutter × UI #02 ~ agexコーポレートサイトをトレースしてみた (スライダー編 part1) ~
Flutter × UI #03 ~ agexコーポレートサイトをトレースしてみた (スライダー編 part2) ~
Flutter × UI #04 ~ agexコーポレートサイトをトレースしてみた (スライダー編 part3) ~
Flutter × UI #05 ~ agexコーポレートサイトをトレースしてみた (スライダー編 part4) ~
Flutter × UI #06 ~ agexコーポレートサイトをトレースしてみた (スライダー編 part5) ~
○ ブログアイテム編
Flutter × UI #07 ~ agexコーポレートサイトをトレースしてみた (ブログアイテム編 part1) ~
今回のおはなし
今回は、弊社HPの「ブログアイテム」をFlutterでトレースした際のおはなし part2です。
引きづづき、実装を進めていきます。
[ここまでの成果]
・ アイキャッチ画像がブログアイテム上部に配置される(以降、アイキャッチ要素)
・ アイキャッチ画像下部に、やや左側にずれる形でタイトルを含む矩形要素が配置される(以降、タイトル要素)
・ ブログアイテムは、表示時ズームインアニメーションで表示される
・ ブログアイテムは、マウスホバー時にアイテム全体がややズームされる
再現してみる
今回は、「#07 ブログアイテム編 part1」で作成したブログアイテムの基本形に、アニメーションをつけていきます。
ブログアイテムは、表示時ズームインアニメーションで表示される
これは、「animate_do」というパッケージを使用して実装することにします。
このパッケージで提供されている「ZoomIn」という機能(Widget)を利用することで、表示時のズームインアニメーションを再現することができます。
class BlogItem extends StatelessWidget {
BlogItem({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ZoomIn( // 「ZoomIn」Widgetでブログアイテムをラップする
duration: Duration(milliseconds: 300), // durationを設定
child: ConstrainedBox(
constraints: const BoxConstraints.expand(
width: 370,
height: 380,
),
・
・
・
),
),
);
}
}
たったこれだけの実装変更で、以下のようなズームインアニメーションをブログアイテムに追加することができます。
ブログアイテムは、マウスホバー時にアイテム全体がややズームされる
マウスホバーのイベント処理については、今までと同様に「MouseRegion」Widgetを利用します。「Stack」Widgetをラップする形で「MouseRegion」を利用してしまうと、「Stack」Widget内における、アイキャッチ要素・タイトル要素が存在しない箇所にマウスが移動した際にも、「onEnter」イベントが発火してしまいます。そのため今回は、アイキャッチ要素・タイトル要素それぞれを「MouseRegion」Widgetでラップします。
Stack(
children: [
Positioned(
left: 70,
top: 0,
child: MouseRegion(
onEnter: (detail) => _onEnterHandler(detail, context),
onExit: (detail) => _onExitHandler(detail, context),
child: Container( // アイキャッチ要素
width: 300,
height: 250,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(‘lib/assets/images/eyecatch.png’),
),
),
),
),
),
Positioned(
left: 0,
top: 180,
child: MouseRegion(
onEnter: (detail) => _onEnterHandler(detail, context),
onExit: (detail) => _onExitHandler(detail, context),
child: Container( // タイトル要素
width: 300,
height: 200,
color: Colors.lightBlue[300],
child: Center(
child: Text(
“Title”,
style: TextStyle(
color: Colors.white,
fontSize: 40
),
),
),
),
),
),
],
),
void _onEnterHandler(PointerEvent details, BuildContext context) {
// ズームイン
}
void _onExitHandler(PointerEvent details, BuildContext context) {
// ズームアウト
}
これで、アイキャッチ要素・タイトル要素それぞれにマウスホバーイベント処理の準備ができました。ここで準備した各ハンドラーに対して、ズームイン・ズームアウトの処理を記述すれば良いことになります。
ズームイン・ズームアウトアニメーションについては「#05 スライダー編 part4」でも紹介したように、animationControllerを利用してスケール値を遷移させ、そのスケール値をWidgetのスケールとして利用することで実現することができます。
今回はWidget全体のスケールを変化させる必要があるため、「Transform.scale」を利用します。このWidgetの「scale」プロパティに対して、上記のスケール値をセットすることで、子要素をそのスケール値に応じたサイズに変化させることが出来きます。
// StatefulWidgetに変更
class BlogItem extends StatefulWidget {
BlogItem({Key key}) : super(key: key);
@override
_BlogItemState createState() => _BlogItemState();
}
class _BlogItemState extends State with TickerProviderStateMixin {
AnimationController zoomController;
Animation zoomAnimation;
Animation zoomCurvedAnimation;
@override
void initState() {
super.initState();
zoomController = AnimationController(
duration: const Duration(milliseconds: 50),
vsync: this,
);
zoomController.addListener(() {
setState(() {});
});
zoomCurvedAnimation = CurvedAnimation(
parent: zoomController,
curve: Curves.linear,
);
zoomAnimation = Tween(
begin: 1.0,
end: 1.03,
).animate(zoomCurvedAnimation);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Transform.scale(
scale: zoomAnimation.value,
child: ZoomIn(
・
・
・
),
),
);
}
void _onEnterHandler(PointerEvent details, BuildContext context) {
zoomController.stop();
zoomController.forward();
}
void _onExitHandler(PointerEvent details, BuildContext context) {
zoomController.stop();
zoomController.reverse();
}
}
これにより、以下のようにアイキャッチ要素・タイトル要素へのマウスホバー時に、ブログアイテム全体がズームされ、マウスが要素外へ移動した際にズームアウトするようなアニメーションを付けることができます。
なんと、この実装によりブログアイテムの実装が完了してしまいました!
[ここまでの成果]
・ アイキャッチ画像がブログアイテム上部に配置される(以降、アイキャッチ要素)
・ アイキャッチ画像下部に、やや左側にずれる形でタイトルを含む矩形要素が配置される(以降、タイトル要素)
・ ブログアイテムは、表示時ズームインアニメーションで表示される
・ ブログアイテムは、マウスホバー時にアイテム全体がややズームされる
要素が少ないこともあり、あっさり実装を終えることができました!
次回からは、「ブログリスト編」を開始しようと思います。これがまた難しい。。。
今日の一言
今までの記事で紹介したことの組み合わせで、様々な要素を再現できるようになってきました。まだまだ積み重ねが足りないので引き続き学習を続けながら、学んだことをご紹介できればと思います!
コンサルティング事業について詳しく知りたい方はこちら
RECOMMEND
おすすめ記事