-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathloading_animation.dart
116 lines (100 loc) · 3.44 KB
/
loading_animation.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import 'dart:ui' as ui; //to avoid conflict
import 'package:flutter/material.dart';
class LoadingAnimation extends StatefulWidget {
const LoadingAnimation({super.key});
@override
State<LoadingAnimation> createState() => _LoadingAnimationState();
}
class _LoadingAnimationState extends State<LoadingAnimation>
with TickerProviderStateMixin {
//definition of the text with textPainter in order to get its width
final textPainter = TextPainter(
textDirection: TextDirection.ltr,
text: const TextSpan(
text: "Loading...",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 34)))
..layout(maxWidth: 200);
late final AnimationController _animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 1))
..repeat(reverse: true);
late final Animation<double> animation =
Tween<double>(begin: 20, end: textPainter.width - 20)
.animate(_animationController);
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromARGB(255, 85, 84, 84),
appBar: AppBar(
automaticallyImplyLeading: true,
title: const Text(
"Loading Animation",
style: TextStyle(color: Colors.white),
),
backgroundColor: const Color.fromARGB(255, 85, 84, 84),
),
body: Center(
child: AnimatedBuilder(
animation: _animationController,
builder: (context, child) {
return CustomPaint(
size: Size(textPainter.width, textPainter.width),
painter: LoadingPainter(circleOffsetdx: animation.value),
);
}),
),
);
}
}
class LoadingPainter extends CustomPainter {
final double circleOffsetdx;
LoadingPainter({required this.circleOffsetdx});
@override
void paint(Canvas canvas, Size size) {
//background text painter
final backgroundtextPainter = TextPainter(
textDirection: TextDirection.ltr,
text: const TextSpan(
text: "Loading...",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 34)));
//prepare text
backgroundtextPainter.layout(maxWidth: 152);
//paint text
backgroundtextPainter.paint(canvas, Offset.zero);
//definition of the circle
final Path path = Path()
..addOval(
Rect.fromCircle(center: Offset(circleOffsetdx, 20), radius: 20));
// save the current layout of the canvas before cliping
// the foreground text
canvas.save();
//clip the circle to constraint what will follow (the foreground text)
canvas.clipPath(path);
// foreground text painter
final foregroundTextPainter = TextPainter(
textDirection: TextDirection.ltr,
text: TextSpan(
text: "Loading...",
style: TextStyle(
color: Colors.white,
background: ui.Paint()..color = Colors.black,
fontWeight: FontWeight.bold,
fontSize: 34)));
foregroundTextPainter.layout(maxWidth: 152);
foregroundTextPainter.paint(canvas, Offset.zero);
//restore the initial layout
//useful in case there are other things to draw
canvas.restore();
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}