dev
dart 61 lines 1.53 KB
Raw
1 import 'dart:math' as math;
2 import 'package:flutter/material.dart';
3
4 class FlipCard extends StatefulWidget {
5 const FlipCard({
6 super.key,
7 required this.front,
8 required this.back,
9 this.duration = const Duration(milliseconds: 400),
10 this.flipOnTouch = true,
11 });
12
13 final Widget front;
14 final Widget back;
15 final Duration duration;
16 final bool flipOnTouch;
17
18 @override
19 FlipCardState createState() => FlipCardState();
20 }
21
22 class FlipCardState extends State<FlipCard> with SingleTickerProviderStateMixin {
23 late final AnimationController _ctrl =
24 AnimationController(vsync: this, duration: widget.duration);
25 bool _isFront = true;
26
27 void toggleCard() {
28 if (_isFront) {
29 _ctrl.forward();
30 } else {
31 _ctrl.reverse();
32 }
33 _isFront = !_isFront;
34 }
35
36 @override
37 Widget build(BuildContext context) {
38 final content = AnimatedBuilder(
39 animation: _ctrl,
40 builder: (_, __) {
41 final angle = _ctrl.value * math.pi;
42 final isFront = angle < math.pi / 2;
43 return Transform(
44 alignment: Alignment.center,
45 transform: Matrix4.identity()
46 ..setEntry(3, 2, 0.001)
47 ..rotateY(angle),
48 child: isFront
49 ? widget.front
50 : Transform(
51 alignment: Alignment.center,
52 transform: Matrix4.rotationY(math.pi),
53 child: widget.back,
54 ),
55 );
56 },
57 );
58
59 return widget.flipOnTouch ? GestureDetector(onTap: toggleCard, child: content) : content;
60 }
61 }