i'm trying to make a widget like the one availible in the most QR scanning apps
like in this image
having the resizable square trensparent and we can click through it,and alwayes entoured with a dark color with opacity ,the dark color should occupe all the scrren except the resiazable area. the widget is overlayed over all the screen.
i tried this code (don't remembre the link where i found it,and i did some changes)
this is the code result
class ImageManager extends StatefulWidget {
const ImageManager({super.key});
@override
State<ImageManager> createState() => _ImageManagerState();
}
const double _kballRadius = 10;
class _ImageManagerState extends State<ImageManager> {
double _x = 0;
double _y = 0;
double _height = 300;
double _width = 300;
final double _aspectRatio = 300 / 300;
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return Stack(
children: <Widget>[
Positioned(
top: _y.clamp(0, screenHeight - _height),
left: _x.clamp(0, screenWidth - _width - _kballRadius),
child: GestureDetector(
onTap: () {},
onPanUpdate: (DragUpdateDetails details) {
setState(() {
_x += details.delta.dx;
_y += details.delta.dy;
});
},
child: Container(
height: _height + 10,
width: _width + 10,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: Colors.transparent,
),
)),
),
// top left
Positioned(
top: _y.clamp(0, screenHeight - _height) - _kballRadius,
left: _x.clamp(0, screenWidth - _width - _kballRadius) - _kballRadius,
child: Ball(
kballRadius: _kballRadius,
onDragStart: () {},
onDrag: onDragTopLeft,
onDragEnd: () {},
),
),
// top right
Positioned(
top: _y.clamp(0, screenHeight - _height) - _kballRadius,
left: _x.clamp(0, screenWidth - _width - _kballRadius) +
_width -
_kballRadius,
child: Ball(
kballRadius: _kballRadius,
onDragStart: () {},
onDrag: _onDragTopRight,
onDragEnd: () {},
),
),
// bottom left
Positioned(
top: _y.clamp(0, screenHeight - _height) + _height - _kballRadius,
left: _x.clamp(0, screenWidth - _width - _kballRadius) - _kballRadius,
child: Ball(
kballRadius: _kballRadius,
onDragStart: () {},
onDrag: _onDragBottomLeft,
onDragEnd: () {},
),
),
// bottom right
Positioned(
top: _y.clamp(0, screenHeight - _height) + _height - _kballRadius,
left: _x.clamp(0, screenWidth - _width - _kballRadius) +
_width -
_kballRadius,
child: Ball(
kballRadius: _kballRadius,
onDragStart: () {},
onDrag: _onDragBttomRight,
onDragEnd: () {},
),
),
],
);
}
onDragTopLeft(double dx, double dy) {
var newWidth = _width - dx;
// var newHeight = newWidth * _aspectRatio;
var newHeight = _height * _aspectRatio - dy;
setState(() {
_y = _y + (_height - newHeight);
_x = _x + dx;
_width = newWidth;
_height = newHeight;
});
}
_onDragTopRight(double dx, double dy) {
var newWidth = _width + dx;
// var newHeight = newWidth * _aspectRatio;
var newHeight = _height * _aspectRatio - dy;
setState(() {
_y = _y + (_height - newHeight);
_width = newWidth;
_height = newHeight;
});
}
_onDragBttomRight(double dx, double dy) {
var newWidth = _width + dx;
var newHeight = _height * _aspectRatio + dy;
setState(() {
_width = newWidth;
_height = newHeight;
});
}
_onDragBottomLeft(double dx, double dy) {
var newWidth = _width - dx;
var newHeight = _height * _aspectRatio + dy;
setState(() {
_x = _x + dx;
_width = newWidth;
_height = newHeight;
});
}
}