I have a Positioned widget that is draggable, by using Offset and wrapping it inside a Gesture Detector to update its position, and I want to constrain the area that this widget can move, so it cannot go beyond the boundaries. The structure is like this:
As it is shown below, I want the circle to move only in the are inside the gray lines. Is it possible?
Provide 2x value as limit, I did for touch position purpose. also, both dx and dy axis can work separately. If you don't want it, you can combine two condition on a single setState.
Result
Widget
class HomeWidget extends StatefulWidget {
@override
_HomeWidgetState createState() => _HomeWidgetState();
}
class _HomeWidgetState extends State<HomeWidget> {
double dx = 0;
double dy = 0;
get limit => 50;
get containerSize => 50;
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: [
Positioned(
left: limit * .5,
child: Container(
height: constraints.maxHeight,
width: 5,
color: Colors.grey,
),
),
Positioned(
bottom: limit * .5,
child: Container(
width: constraints.maxWidth,
height: 5,
color: Colors.grey,
),
),
Positioned(
top: dy - containerSize * .5,
left: dx - containerSize * .5,
child: Container(
height: containerSize,
width: containerSize,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.deepPurple,
),
),
),
GestureDetector(
onPanUpdate: (details) {
if (details.localPosition.dx > limit)
setState(() {
dx = details.localPosition.dx;
});
if (details.localPosition.dy < constraints.maxHeight - limit)
setState(() {
dy = details.localPosition.dy;
});
print(" $dx, $dy ");
},
),
],
),
),
);
}
}