Skip to content

Instantly share code, notes, and snippets.

@CoderNamedHendrick
Created February 7, 2022 20:06
Show Gist options
  • Save CoderNamedHendrick/67b9419aac0c9ad3cea2bf8fe208fcd4 to your computer and use it in GitHub Desktop.
Save CoderNamedHendrick/67b9419aac0c9ad3cea2bf8fe208fcd4 to your computer and use it in GitHub Desktop.
This gist is used to create a wheeel that rotates on hover on desktop and web and on tap on mobile.
class WheelScreen extends StatelessWidget {
const WheelScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Center(
child: SizedBox(
height: 300,
width: 300,
child: RotateWheel(),
),
);
}
}
class RotateWheel extends StatefulWidget {
const RotateWheel({Key? key}) : super(key: key);
@override
_RotateWheelState createState() => _RotateWheelState();
}
class _RotateWheelState extends State<RotateWheel>
with SingleTickerProviderStateMixin {
bool _isHovered = false;
late AnimationController _controller;
late Animation<double> _wheelAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 600),
);
_wheelAnimation =
Tween<double>(begin: -math.pi, end: math.pi).animate(_controller)
..addListener(() {
setState(() {});
});
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.forward(from: -math.pi);
} else if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});
// _controller.forward();
}
@override
Widget build(BuildContext context) {
if (Platform.isAndroid || Platform.isIOS) {
return GestureDetector(
onTap: () => setState(() {
_isHovered = !_isHovered;
onEnter(_isHovered);
}),
child: Transform.rotate(
angle: _wheelAnimation.value,
child: CustomPaint(
painter: WheelPainter(),
child: Container(),
),
),
);
} else {
return MouseRegion(
onEnter: (event) => onEnter(true),
onExit: (event) => onEnter(false),
child: Transform.rotate(
angle: _wheelAnimation.value,
child: CustomPaint(
painter: WheelPainter(),
child: Container(),
),
),
);
}
}
void onEnter(bool isHovered) {
if (!isHovered) {
_controller.stop(canceled: false);
} else {
_controller.forward();
}
}
}
class WheelPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..strokeWidth = 10
..color = Colors.black
..style = PaintingStyle.stroke;
Offset center = Offset(size.width / 2, size.height / 2);
canvas.drawCircle(center, 150, paint);
paint = Paint()..color = Colors.black;
canvas.drawCircle(center, 45, paint);
// 3rd quadrant
paint = Paint()
..color = Colors.black54
..style = PaintingStyle.fill;
Path path = Path()
..moveTo(size.width / 2, (size.height / 2) - 45)
..lineTo(size.width / 2, (size.height / 2) - 145)
..quadraticBezierTo((size.width / 2) + 135, (size.height / 2) - 135,
(size.width / 2) + 145, size.height / 2)
..lineTo((size.width / 2) + 145, size.height / 2)
..lineTo((size.width / 2) + 45, size.height / 2)
..quadraticBezierTo((size.width / 2) + 40, (size.height / 2) - 40,
size.width / 2, (size.height / 2) - 45);
path.close();
canvas.drawPath(path, paint);
// 1st quadrant
paint = Paint()
..color = Colors.black54
..style = PaintingStyle.fill;
path = Path()
..moveTo(size.width / 2, (size.height / 2) + 45)
..lineTo(size.width / 2, (size.height / 2) + 145)
..quadraticBezierTo((size.width / 2) - 135, (size.height / 2) + 135,
(size.width / 2) - 145, size.height / 2)
..lineTo((size.width / 2) - 145, size.height / 2)
..lineTo((size.width / 2) - 45, size.height / 2)
..quadraticBezierTo((size.width / 2) - 40, (size.height / 2) + 40,
size.width / 2, (size.height / 2) + 45)
..close();
canvas.drawPath(path, paint);
// 4th quadrant
paint = Paint()
..color = Colors.grey
..style = PaintingStyle.fill;
path = Path()
..moveTo(size.width / 2, (size.height / 2) + 45)
..lineTo(size.width / 2, (size.height / 2) + 145)
..quadraticBezierTo((size.width / 2) + 135, (size.height / 2) + 135,
(size.width / 2) + 145, size.height / 2)
..lineTo((size.width / 2) + 145, size.height / 2)
..lineTo((size.width / 2) + 45, size.height / 2)
..quadraticBezierTo((size.width / 2) + 40, (size.height / 2) + 40,
size.width / 2, (size.height / 2) + 45);
path.close();
canvas.drawPath(path, paint);
// 2nd quadrant
paint = Paint()
..color = Colors.grey
..style = PaintingStyle.fill;
path = Path()
..moveTo(size.width / 2, (size.height / 2) - 45)
..lineTo(size.width / 2, (size.height / 2) - 145)
..quadraticBezierTo((size.width / 2) - 135, (size.height / 2) - 135,
(size.width / 2) - 145, size.height / 2)
..lineTo((size.width / 2) - 145, size.height / 2)
..lineTo((size.width / 2) - 45, size.height / 2)
..quadraticBezierTo((size.width / 2) - 40, (size.height / 2) - 40,
size.width / 2, (size.height / 2) - 45)
..close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment