How to draw a hexagon shape in flutter? - flutter

I wanted to draw a hexagon shape but I couldn't do what I wanted.
this is my result:
Path createHexagonPath() {
const int SIDES_OF_HEXAGON = 6;
const double radius = 50;
const Offset center = Offset(50, 50);
final path = Path();
var angle = (pi * 2) / SIDES_OF_HEXAGON;
Offset firstPoint = Offset(radius * cos(0.0), radius * sin(0.0));
path.moveTo(firstPoint.dx + center.dx, firstPoint.dy + center.dy);
for (int i = 1; i <= SIDES_OF_HEXAGON; i++) {
double x = radius * cos(angle * i) + center.dx;
double y = radius * sin(angle * i) + center.dy;
path.lineTo(x, y);
}
path.close();
return path;
}
I want that to be the case:

go over to this website https://fluttershapemaker.com it is simple and easy

you can try this, polygon_clipper with flutter_neumorphic
Neumorphic(
style: NeumorphicStyle(
depth: -5,
lightSource: LightSource.topLeft,
color: Colors.grey
),
child:
ClipPolygon(
sides: 6,
borderRadius: 5.0, // Default 0.0 degrees
rotate: 90.0, // Default 0.0 degrees
boxShadows: [
PolygonBoxShadow(color: Colors.black, elevation: 1.0),
PolygonBoxShadow(color: Colors.grey, elevation: 5.0)
],
child: Container(color: Colors.black),
),
)

Related

Flutter Segmented Ring Around Number

In Flutter I try to make a segmented ring (or radial gauge) around a number to indicate its value. Like here
The example of in the link is already a solution itself, however, I read syncfusion widgets are not free. (I am using it commercially)
Any alternatives or ideas how to set this into practice?
You can use CustomPainter to achieve the same,
class RingPainter extends CustomPainter {
const RingPainter({
required this.percentage,
this.startColor,
this.endColor,
this.width,
}) : assert(percentage >= 0 && percentage <= 100,
"Percentage must be in the range 0-100!");
final double percentage;
final Color? startColor;
final Color? endColor;
final double? width;
double get progress => percentage / 100;
#override
void paint(Canvas canvas, Size size) {
var angle = math.pi / 180 * 230;
canvas.rotateAroundCenter(size, angle);
canvas.drawRing(
size,
1,
startColor: Colors.black12,
endColor: Colors.black12,
width: width,
);
canvas.drawRing(
size,
progress,
startColor: startColor,
endColor: endColor,
width: width,
);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
extension on Canvas {
rotateAroundCenter(Size size, double angleInRadians) {
final double r =
math.sqrt(size.width * size.width + size.height * size.height) / 2;
final alpha = math.atan(size.height / size.width);
final beta = alpha + angleInRadians;
final shiftY = r * math.sin(beta);
final shiftX = r * math.cos(beta);
final translateX = size.width / 2 - shiftX;
final translateY = size.height / 2 - shiftY;
translate(translateX, translateY);
rotate(angleInRadians);
}
drawRing(
Size size,
double value, {
Color? startColor,
Color? endColor,
double? width,
}) {
final rect = Rect.fromLTWH(-15, 0.0, size.width, size.height);
final gradient = SweepGradient(
startAngle: 3 * math.pi / 2,
endAngle: 7 * math.pi / 2,
tileMode: TileMode.repeated,
colors: [
startColor ?? Colors.pink,
endColor ?? Colors.blueAccent,
],
);
final paint = Paint()
..shader = gradient.createShader(rect)
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = width ?? 24;
final center = Offset(size.width / 2, size.height / 2);
final radius =
math.min(size.width / 2, size.height / 2) - ((width ?? 24) / 2);
const startAngle = -math.pi / 2;
final sweepAngle = 2 * math.pi * value * 0.723;
drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
}
Use it with CustomPaint widget,
CustomPaint(
painter: RingPainter(
percentage: 70,
width: 20,
),
)
In case, you want text inside ring,
Center(
child: SizedBox(
width: 200,
height: 200,
child: Stack(
fit: StackFit.expand,
children: [
const Center(
child: Text(
"70%",
style: TextStyle(
fontSize: 48,
fontWeight: FontWeight.w900,
color: Colors.purple,
),
),
),
CustomPaint(
painter: RingPainter(
percentage: 70,
width: 20,
),
),
],
),
),
)

Take picture when specific object detected

I'm trying to make my app take a picture when certain objects is detected. In this case, the object is "Person" and still can't get it to work. The app detects the object but doesn't take a picture. I'm using TFlite for this app.
Here's my code to make take the picture. When the text value from the bounding box turns "Person" it will take the picture or that's what I thought.
if (Detected == "Person") {
controller.stopImageStream();
XFile image = controller.takePicture();
image.saveTo(image.path);
// ignore: use_build_context_synchronously
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(
imagePath: image.path,
),
),
);
}
This is my whole bounding box code
// ignore_for_file: prefer_typing_uninitialized_variables, no_leading_underscores_for_local_identifiers
import 'package:camera/camera.dart';
import 'package:camera_test/detection/l_camera.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
class BoundingBox extends StatelessWidget {
final List<dynamic> results;
final int previewH;
final int previewW;
final double screenH;
final double screenW;
const BoundingBox(
this.results, this.previewH, this.previewW, this.screenH, this.screenW,
{super.key});
get controller => null;
#override
Widget build(BuildContext context) {
List<Widget> _renderBox() {
//daripada result akan ubah bounding box
return results.map((re) {
var _x = re["rect"]["x"];
var _w = re["rect"]["w"];
var _y = re["rect"]["y"];
var _h = re["rect"]["h"];
var scaleW, scaleH, x, y, w, h;
final String Detected = "${re["detectedClass"]}";
if (screenH / screenW > previewH / previewW) {
scaleW = screenH / previewH * previewW;
scaleH = screenH;
var difW = (scaleW - screenW) / scaleW;
x = (_x - difW / 2) * scaleW;
w = _w * scaleW;
if (_x < difW / 2) w -= (difW / 2 - _x) * scaleW;
y = _y * scaleH;
h = _h * scaleH;
} else {
scaleH = screenW / previewW * previewH;
scaleW = screenW;
var difH = (scaleH - screenH) / scaleH;
x = _x * scaleW;
w = _w * scaleW;
y = (_y - difH / 2) * scaleH;
h = _h * scaleH;
if (_y < difH / 2) h -= (difH / 2 - _y) * scaleH;
}
if (Detected == "Person") {
controller.stopImageStream();
XFile image = controller.takePicture();
image.saveTo(image.path);
// ignore: use_build_context_synchronously
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(
imagePath: image.path,
),
),
);
}
return Positioned(
left: math.max(0, x),
top: math.max(0, y),
width: w,
height: h,
child: Container(
padding: const EdgeInsets.only(top: 5.0, left: 5.0),
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromARGB(255, 77, 255, 0),
width: 3.0,
),
),
child: Text(
"${re["detectedClass"]} ${(re["confidenceInClass"] * 100).toStringAsFixed(0)}%",
style: const TextStyle(
color: Color.fromARGB(255, 77, 255, 0),
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
),
);
}).toList();
}
return Stack(
children: _renderBox(),
);
}
}

Slicing a circular container in which each slice behaves like a tab in Flutter

I am trying to achieve a circular widget in which each slice represents a tab and having a separation line between each slice coming out from the centre of the circle as shown in the image.
I have tried bunch of packages and I found the following package fulfilling the purpose to some extent. https://pub.dev/packages/circular_widgets
I have also tried with Clipping and Custom painting API, but couldn't achieve what i am looking for.
I made custom painter with widgets
I hope this help you
class CircleCustomPainer extends CustomPainter {
var count = 6;
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint();
paint.color = Colors.red;
Paint paint1 = Paint();
paint1.color = Colors.white;
paint1.strokeWidth = 4;
paint1.style = PaintingStyle.stroke;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2), size.height / 2, paint);
Path path = Path();
path.moveTo(size.width / 2, size.height / 2);
for (var i = 0; i < count; i++) {
var o = (2 * i * math.pi) / count;
var x = 150 * math.cos(o) + (size.width / 2);
var y = 150 * math.sin(o) + (size.height / 2);
path.lineTo(x, y);
path.moveTo(size.width / 2, size.height / 2);
}
canvas.drawPath(path, paint1);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
this is widget creator for menu
Widget getWidgets(int count, Size size) {
List<Widget> list = [];
for (var i = 0; i < count; i++) {
var o = (2 * i * math.pi) / count;
o = o + ((360 / count) / 57.2958) / 2;
var x = (size.width / 3) * math.cos(o) + (size.width / 2);
var y = (size.width / 3) * math.sin(o) + (size.height / 2);
list.add(Positioned.fromRect(
rect: Rect.fromCenter(center: Offset(x, y), height: 60, width: 60),
child: Column(
children: [
Container(
color: Colors.black,
width: 60,
height: 60,
),
],
),
));
}
return Container(
width: 300,
height: 300,
alignment: Alignment.center,
child: Stack(
children: list,
),
);
}
you can used like this
SizedBox(
width: 300,
height: 300,
child: Stack(
alignment: Alignment.center,
children: [
CustomPaint(
size: Size(300, 300),
painter: CircleCustomPainer(),
),
Center(child: getWidgets(6, Size(300, 300)))
],
),
)
I will probably create a youtube video for that

Flutter Custom Clipper Radius Octogone

I'm trying to round off the shapes of my clipper but it's impossible. I tried with the path.arcToPoint property but I think I don't really understand how it works to add radius on path. Only with arcToPoint property ?
I put my Clipper class and the code to call the clipper here :
ClipPath(
clipper: Clipper(points: 8),
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Color.red,
),
child: Center(child: Text('1'),
),
);
class Clipper extends CustomClipper<Path> {
Clipper({this.points = 8});
/// The number of points of the star
final int points;
#override
Path getClip(Size size) {
double width = size.width;
double halfWidth = width / 2;
double bigRadius = halfWidth;
double radius = halfWidth / 1.25;
double degreesPerStep = _degToRad(360 / points);
double halfDegreesPerStep = degreesPerStep / 2;
var path = Path();
double max = 2 * math.pi;
path.moveTo(width, halfWidth);
for (double step = 0; step < max; step += degreesPerStep) {
path.lineTo(halfWidth + bigRadius * math.cos(step), halfWidth + bigRadius * math.sin(step));
path.arcToPoint(
Offset(
halfWidth + bigRadius * math.cos(step),
halfWidth + bigRadius * math.sin(step),
),
radius: const Radius.circular(50));
path.lineTo(halfWidth + radius * math.cos(step + halfDegreesPerStep), halfWidth + radius * math.sin(step + halfDegreesPerStep));
path.arcToPoint(
Offset(
halfWidth + radius * math.cos(step + halfDegreesPerStep),
halfWidth + radius * math.sin(step + halfDegreesPerStep),
),
radius: const Radius.circular(50));
}
path.close();
return path;
}
double _degToRad(num deg) => deg * (math.pi / 180.0);
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
Clipper oldie = oldClipper as Clipper;
return points != oldie.points;
}
}
Thanks

How to create a dotted border around a box in flutter?

I am building a list of boxes layouts in my app using flutter. I want dotted border around the box. I have used card widget to create the boxes. But, how can I get dotted border around the boxes?
EDIT
I have added this as a package in pub.
Now, all you need to do is
DottedBorder(
color: Colors.black,
gap: 3,
strokeWidth: 1,
child: FlutterLogo(size: 148),
)
Working Solution [Outdated]
Like tomerpacific said in this answer, Flutter does not have a default implementation for dashed border at the moment.
I worked for some time yesterday and was able to come up with a solution using CustomPainter. Hope this helps someone.
Add the DashedRect to your container, like so
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
height: 400,
width: 300,
color: Colors.black12,
child: DashedRect(color: Colors.red, strokeWidth: 2.0, gap: 3.0,),
),
),
);
}
}
DashedRect.dart
import 'package:flutter/material.dart';
import 'dart:math' as math;
class DashedRect extends StatelessWidget {
final Color color;
final double strokeWidth;
final double gap;
DashedRect(
{this.color = Colors.black, this.strokeWidth = 1.0, this.gap = 5.0});
#override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: EdgeInsets.all(strokeWidth / 2),
child: CustomPaint(
painter:
DashRectPainter(color: color, strokeWidth: strokeWidth, gap: gap),
),
),
);
}
}
class DashRectPainter extends CustomPainter {
double strokeWidth;
Color color;
double gap;
DashRectPainter(
{this.strokeWidth = 5.0, this.color = Colors.red, this.gap = 5.0});
#override
void paint(Canvas canvas, Size size) {
Paint dashedPaint = Paint()
..color = color
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
double x = size.width;
double y = size.height;
Path _topPath = getDashedPath(
a: math.Point(0, 0),
b: math.Point(x, 0),
gap: gap,
);
Path _rightPath = getDashedPath(
a: math.Point(x, 0),
b: math.Point(x, y),
gap: gap,
);
Path _bottomPath = getDashedPath(
a: math.Point(0, y),
b: math.Point(x, y),
gap: gap,
);
Path _leftPath = getDashedPath(
a: math.Point(0, 0),
b: math.Point(0.001, y),
gap: gap,
);
canvas.drawPath(_topPath, dashedPaint);
canvas.drawPath(_rightPath, dashedPaint);
canvas.drawPath(_bottomPath, dashedPaint);
canvas.drawPath(_leftPath, dashedPaint);
}
Path getDashedPath({
#required math.Point<double> a,
#required math.Point<double> b,
#required gap,
}) {
Size size = Size(b.x - a.x, b.y - a.y);
Path path = Path();
path.moveTo(a.x, a.y);
bool shouldDraw = true;
math.Point currentPoint = math.Point(a.x, a.y);
num radians = math.atan(size.height / size.width);
num dx = math.cos(radians) * gap < 0
? math.cos(radians) * gap * -1
: math.cos(radians) * gap;
num dy = math.sin(radians) * gap < 0
? math.sin(radians) * gap * -1
: math.sin(radians) * gap;
while (currentPoint.x <= b.x && currentPoint.y <= b.y) {
shouldDraw
? path.lineTo(currentPoint.x, currentPoint.y)
: path.moveTo(currentPoint.x, currentPoint.y);
shouldDraw = !shouldDraw;
currentPoint = math.Point(
currentPoint.x + dx,
currentPoint.y + dy,
);
}
return path;
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
I do not expect this to fit in with all use cases and there is a lot of room for customization and improvement. Comment if you find any bugs.
You can use dotted_border Flutter package
return DottedBorder(
borderType: BorderType.RRect,
radius: Radius.circular(20),
dashPattern: [10, 10],
color: Colors.grey,
strokeWidth: 2,
child: Card(
color: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Center(child: Text("hi")),
)
There is an one plugin for draw dotted border around widgets
https://pub.dev/packages/dotted_border
Using this plugin you can draw dotted or dashed border
//1. Install the plugin by add dependencies in pubspace.yaml
dotted_border: ^1.0.6
Add below code for show border
DottedBorder(
color: Colors.black,
strokeWidth: 1,
child: FlutterLogo(size: 148),
)
BorderStyle.none can be useful if you wanna apply some animation or remove\add border function onTap(like a lighting border) event or similar.