Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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);
- }
Add Comment
Please, Sign In to add comment