Skip to content

Instantly share code, notes, and snippets.

@alwerr
Created March 16, 2024 08:18
Show Gist options
  • Save alwerr/9388c95f67f3dbd7bf3a829a833bd59a to your computer and use it in GitHub Desktop.
Save alwerr/9388c95f67f3dbd7bf3a829a833bd59a to your computer and use it in GitHub Desktop.
The full code , I just want to know what color is under the black cube when or after the user spins the wheel
import 'package:flutter/material.dart';
import 'dart:math';
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.center,
children: [
Positioned(
bottom: 40,
child: Pie(
onTap: () {},
onSpin: (p0) {},
),
),
Positioned(
top: 180,
child: Container(
width: 30,
height: 30,
color: Colors.black,
),
),
],
),
);
}
}
class Pie extends StatefulWidget {
const Pie({super.key, required this.onSpin, required this.onTap}); // changed
final Function() onTap;
final Function(double) onSpin;
@override
PieState createState() => PieState();
}
class PieState extends State<Pie> {
double finalAngle = 0.0;
double oldAngle = 0.0;
double upsetAngle = 0.0;
@override
Widget build(BuildContext context) {
return _defaultApp(context);
}
_defaultApp(BuildContext context) {
return SizedBox(
width: 300,
height: 300,
child: LayoutBuilder(
builder: (context, constraints) {
Offset centerOfGestureDetector = Offset(constraints.maxWidth / 2, constraints.maxHeight / 2);
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: widget.onTap,
onPanStart: (details) {
final touchPositionFromCenter = details.localPosition - centerOfGestureDetector;
upsetAngle = oldAngle - touchPositionFromCenter.direction;
},
onPanEnd: (details) {
setState(
() {
oldAngle = finalAngle;
},
);
},
onPanUpdate: (details) {
final touchPositionFromCenter = details.localPosition - centerOfGestureDetector;
setState(
() {
finalAngle = touchPositionFromCenter.direction + upsetAngle;
},
);
widget.onSpin(finalAngle);
},
child: Transform.rotate(
angle: finalAngle,
child: const PieChart(
data: [30, 30, 30],
customColours: [Colors.amber, Colors.red, Colors.purple],
labels: ['a', 'b', 'c'],
textStyle: TextStyle(),
),
),
);
},
),
);
}
}
class PieChart extends StatelessWidget {
final List<double> data;
final List<String> labels;
final double angleOffset;
final double radius;
final List<Color> customColours;
final TextStyle textStyle;
const PieChart({
super.key,
required this.data,
required this.labels,
required this.customColours,
required this.textStyle,
this.angleOffset = 0,
this.radius = 100,
});
@override
Widget build(BuildContext context) {
double total = data.fold(0, (previousValue, element) => previousValue + element);
final startAngle = 0 - pi / 2 + angleOffset;
return CustomPaint(
painter: _PieChartPainter(
data,
labels,
total,
startAngle,
customColours,
textStyle,
),
size: Size.fromRadius(radius),
);
}
}
class _PieChartPainter extends CustomPainter {
final List<double> data;
final List<String> labels;
final double total;
final double startAngle;
final List<Color> customColours;
final TextStyle textStyle;
_PieChartPainter(
this.data,
this.labels,
this.total,
this.startAngle,
this.customColours,
this.textStyle,
);
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = min(size.width, size.height) / 2;
final rect = Rect.fromCircle(center: center, radius: radius);
final paint = Paint()..style = PaintingStyle.fill;
double sweepAngle = 0;
for (int i = 0; i < data.length; i++) {
final ratio = data[i] / total;
final sweepRad = ratio * 2 * pi;
paint.color = _getColor(i);
canvas.drawArc(rect, startAngle + sweepAngle, sweepRad, true, paint);
final labelAngle = startAngle + sweepAngle + sweepRad / 2;
final labelX = center.dx + (radius * 0.6) * cos(labelAngle);
final labelY = center.dy + (radius * 0.6) * sin(labelAngle);
final labelOffset = Offset(labelX, labelY);
_drawLabel(canvas, labels[i], labelOffset);
sweepAngle += sweepRad;
}
}
void _drawLabel(Canvas canvas, String label, Offset offset) {
final textSpan = TextSpan(
text: label,
style: textStyle,
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout();
final textOffset = Offset(offset.dx - textPainter.width / 2, offset.dy - textPainter.height / 2);
textPainter.paint(canvas, textOffset);
}
Color _getColor(int index) {
return customColours[index % customColours.length];
}
@override
bool shouldRepaint(_PieChartPainter oldDelegate) {
return oldDelegate.data != data ||
oldDelegate.labels != labels ||
oldDelegate.total != total ||
oldDelegate.startAngle != startAngle;
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyWidget(),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment