-
Notifications
You must be signed in to change notification settings - Fork 53
/
medium_clap.dart
89 lines (77 loc) · 2.21 KB
/
medium_clap.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
// This implements Medium's clap button
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Portal(
child: MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Example'),
),
body: const Center(child: ClapButton()),
),
),
);
}
}
class ClapButton extends StatefulWidget {
const ClapButton({Key? key}) : super(key: key);
@override
_ClapButtonState createState() => _ClapButtonState();
}
class _ClapButtonState extends State<ClapButton> {
int clapCount = 0;
bool hasClappedRecently = false;
Timer? resetHasClappedRecentlyTimer;
@override
Widget build(BuildContext context) {
return PortalTarget(
visible: hasClappedRecently,
// aligns the top-center of `child` with the bottom-center of `portal`
anchor: const Aligned(
target: Alignment.topCenter,
follower: Alignment.bottomCenter,
),
closeDuration: kThemeChangeDuration,
portalFollower: TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: hasClappedRecently ? 1 : 0),
duration: kThemeChangeDuration,
builder: (context, progress, child) {
return Material(
elevation: 8 * progress,
animationDuration: Duration.zero,
borderRadius: const BorderRadius.all(Radius.circular(40)),
child: Opacity(
opacity: progress,
child: child,
),
);
},
child: Padding(
padding: const EdgeInsets.all(8),
child: Text('$clapCount'),
),
),
child: ElevatedButton(
onPressed: _clap,
child: const Icon(Icons.plus_one),
),
);
}
void _clap() {
resetHasClappedRecentlyTimer?.cancel();
resetHasClappedRecentlyTimer = Timer(
const Duration(seconds: 2),
() => setState(() => hasClappedRecently = false),
);
setState(() {
hasClappedRecently = true;
clapCount++;
});
}
}