Created
January 21, 2019 17:43
-
-
Save brianegan/3cecbfc5fa688b4de3c574ed82942c4e to your computer and use it in GitHub Desktop.
Shows how to create some funky spinners
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math' show pi; | |
import 'package:flutter/material.dart'; | |
/// A Widget that can be configured to show funky spinning rectangles! | |
/// | |
/// ### Usage | |
/// | |
/// ``` | |
/// Spinnies( | |
/// duration: Duration(milliseconds: 2500), | |
/// size: Size(150, 150), | |
/// rects: [ | |
/// SpinRect(color: Color(0xFFDB4437), begin: 0.0, end: 1.0), | |
/// SpinRect(color: Color(0xFFF4B400), begin: 0.25, end: 1.25), | |
/// SpinRect(color: Color(0xFF4285F4), begin: 0.5, end: 1.5), | |
/// SpinRect(color: Color(0xFF0F9D58), begin: 0.75, end: 1.75), | |
/// ], | |
/// ); | |
/// ``` | |
class Spinnies extends StatefulWidget { | |
final Duration duration; | |
final Size size; | |
final List<SpinRect> rects; | |
const Spinnies({ | |
Key key, | |
@required this.duration, | |
@required this.size, | |
@required this.rects, | |
}) : super(key: key); | |
@override | |
_SpinniesState createState() => _SpinniesState(); | |
} | |
class _SpinniesState extends State<Spinnies> | |
with SingleTickerProviderStateMixin { | |
AnimationController _controller; | |
@override | |
void initState() { | |
_controller = AnimationController(vsync: this, duration: widget.duration) | |
..forward() | |
..repeat(); | |
super.initState(); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return SizedBox( | |
width: widget.size.width, | |
height: widget.size.height, | |
child: CustomPaint( | |
painter: SpinniesPainter( | |
rects: widget.rects, | |
animation: _controller, | |
), | |
), | |
); | |
} | |
} | |
class SpinniesPainter extends CustomPainter { | |
final List<SpinRect> rects; | |
// We accept the animation for two reasons: first, it drives when the custom | |
// painter should repaint. Second, it allows us to get the current value of | |
// the animation so we can use that to calculate the current rotation of each | |
// SpinRect. | |
final Animation<double> animation; | |
SpinniesPainter({ | |
@required this.rects, | |
@required this.animation, | |
}) : super(repaint: animation); | |
@override | |
void paint(Canvas canvas, Size size) { | |
// Defines the Rect we'll be drawing and it's funky border radii | |
final funkyRect = RRect.fromLTRBAndCorners( | |
0.0, | |
0.0, | |
size.width, | |
size.height, | |
topLeft: Radius.elliptical( | |
size.width * 1.15, | |
size.height * 1.25, | |
), | |
topRight: Radius.elliptical( | |
size.width * 1.40, | |
size.height * 1.40, | |
), | |
bottomRight: Radius.elliptical( | |
size.width * 1.45, | |
size.height * 1.10, | |
), | |
bottomLeft: Radius.elliptical( | |
size.width * 1.10, | |
size.height * 1.25, | |
), | |
); | |
// The drawing portion of the class. It is responsible for drawing all of | |
// the different rectangles. | |
for (final rect in rects) { | |
canvas.save(); | |
// Rotate the correct amount around an origin point | |
canvas.translate(size.width / 2, size.height / 2); | |
canvas.rotate(rect.tween.lerp(animation.value) * pi * 2); | |
canvas.translate(-size.width / 2, -size.height / 2); | |
// Then draw the rectangle | |
canvas.drawRRect( | |
funkyRect, | |
Paint() | |
..blendMode = BlendMode.screen | |
..strokeWidth = rect.strokeWidth | |
..style = PaintingStyle.stroke | |
..color = rect.color); | |
canvas.restore(); | |
} | |
} | |
@override | |
bool shouldRepaint(SpinniesPainter oldDelegate) { | |
return true; | |
} | |
} | |
class SpinRect { | |
final Color color; | |
final double strokeWidth; | |
final Tween<double> tween; | |
SpinRect({ | |
@required this.color, | |
@required double begin, | |
@required double end, | |
this.strokeWidth = 7.0, | |
}) : tween = Tween<double>(begin: begin, end: end); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment