Skip to content

Instantly share code, notes, and snippets.

@tarek360
Last active January 9, 2020 06:02
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save tarek360/e7021a6b1077e0387c05d9bf5a0b59e5 to your computer and use it in GitHub Desktop.
Spinner Demo
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(SpinnerDemo());
}
class SpinnerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(),
theme: ThemeData(brightness: Brightness.dark),
home: Spinner(),
);
}
}
class Spinner extends StatefulWidget {
final Duration loopLength;
Spinner({
Key key,
this.loopLength = const Duration(milliseconds: 3500),
}) : super(key: key);
@override
_SpinnerState createState() => _SpinnerState();
}
class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
AnimationController controller;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 60,
height: 60,
child: AnimatedBuilder(
animation: controller,
builder: (context, child) => CustomPaint(
painter: RingOfCirclesPainter(controller.value),
child: child,
),
child: Center(),
),
);
}
@override
void didUpdateWidget(Spinner oldWidget) {
if (widget.loopLength != oldWidget.loopLength) {
controller.duration = widget.loopLength;
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
controller = AnimationController(duration: widget.loopLength, vsync: this);
controller.repeat();
}
}
class RingOfCirclesPainter extends CustomPainter {
final int n = 5;
final double t;
RingOfCirclesPainter(this.t);
double _ringRadius;
double _waveRadius;
double _ballRadius;
double _gap;
@override
void paint(Canvas canvas, Size size) {
_ringRadius = min(size.width, size.height) * 0.35;
_waveRadius = min(size.width, size.height) * 0.10;
_ballRadius = _waveRadius * 0.7;
_gap = _ballRadius / 2;
canvas.save();
canvas.translate(size.width / 2, size.height / 2);
for (var i = 0; i < n; i++) {
drawCircle(canvas, i, false);
}
for (var i = 0; i < n; i++) {
drawCircle(canvas, i, true);
}
canvas.restore();
}
@override
bool shouldRepaint(RingOfCirclesPainter oldDelegate) => n != oldDelegate.n || t != oldDelegate.t;
void drawCircle(Canvas canvas, int i, bool above) {
final color = circlesColor[i];
var angle0 = (i / n - t) % 1 * (2 * pi);
var angle1 = angle0 - t * (2 * pi);
if (cos(angle1) < 0 == above) {
return;
}
canvas.save();
canvas.rotate(angle0);
canvas.translate((_ringRadius + sin(angle1) * _waveRadius), 0);
var paint = Paint()..strokeWidth = (_gap * 2);
paint
..style = PaintingStyle.fill
..color = color;
canvas.drawCircle(Offset.zero, _ballRadius, paint);
canvas.restore();
}
}
const circlesColor = [AppColors.red, AppColors.amber, AppColors.green, AppColors.purple, AppColors.blue];
class AppColors {
static const red = Color(0xFFED2224);
static const amber = Color(0xFFF69E1D);
static const green = Color(0xFF19AC5B);
static const purple = Color(0xFF8150A0);
static const blue = Color(0xFF347FC2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment