i have one resizable movable container. in this container i have set one image. when all four corner point drag that time image size in increase and when all four mid point drag that time image crop. if top mid point drag that time i have to crop image from the top side if bottom mid point drag that time image crop from the bottom side.
this is the code for the image crop.
import 'package:flutter/material.dart';
import 'package:invitation_card_app/pages/constant.dart';
import '../pages/textEditPage.dart';
class MovableImageBox extends StatefulWidget {
late final _MovableImageBoxState currentWidget;
int index;
MovableImageBox({required this.index});
@override
_MovableImageBoxState createState() {
_MovableImageBoxState currentState = _MovableImageBoxState();
this.currentWidget = currentState;
return currentWidget;
}
}
const ballDiameter = 15.0;
const rotateIconSize = 30.0;
class _MovableImageBoxState extends State<MovableImageBox> {
double width = 300;
double height = 200.0;
double _cropWidth = 150;
double aspectRatio = 200/300;
double _angle = 0.0;
double padding = 0.0;
double rotation = 0.0;
bool _isSelected = true;
double fontSize = 15;
double top = 100;
double left = 100;
double oneFontWidth = 17 ;
String _displayText = "";
@override
void initState() {
super.initState();
}
void updateIsSelected(bool isSelected) {
print(" index = ${widget.index},isSelected = ${isSelected}");
setState(() {
_isSelected = isSelected;
});
}
@override
Widget build(BuildContext context) {
return Stack(children: [
Positioned(
top: top,
left: left,
child: GestureDetector(
onTap: () {
for (var i = 0; i < GlobalState.movableAllWidgets.length; i++) {
print("_addMovableTextBox $i");
GlobalState.movableAllWidgets[i].currentWidget
.updateIsSelected(false);
}
setState(() {
_isSelected = true;
GlobalState.selectedIndex = widget.index;
print("index = ${GlobalState.selectedIndex}");
});
},
onPanDown: (details) {
print("down time width =$width");
print("down time height =$height");
for (var i = 0; i < GlobalState.movableAllWidgets.length; i++) {
print("_addMovableTextBox $i");
GlobalState.movableAllWidgets[i].currentWidget
.updateIsSelected(false);
}
setState(() {
FocusScope.of(context).unfocus();
_isSelected = true;
});
},
onPanUpdate: (details) {
setState(() {
top += details.delta.dy;
left += details.delta.dx;
});
},
child: GestureDetector(
onDoubleTap: () {
},
child: Container(
height: height,
width: width,
padding: EdgeInsets.all(2.0),
decoration:
BoxDecoration(
color: Colors.transparent,
border: Border.all(
width: 2,
color: _isSelected ? Colors.black : Colors.transparent,
),
),
child: ClipRect(
child: Align( alignment: Alignment(
top / height,
left / width,
),
child: Image.asset(
'images/rose1.png',
width: width,
height: height,
),
),
),
),
),
),
),
// top left
if (_isSelected)
Positioned(
top: top - ballDiameter /2 ,
left: left - ballDiameter /2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width - dx;
var newHeight = newWidth * aspectRatio ;
setState(() {
if (newHeight > 10 && newWidth > 10) {
top = top + (height - newHeight) ;
left = left + dx;
height = newHeight;
width = newWidth;
}
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
//top mid
if (_isSelected && (width > 10 && height > 10))
Positioned(
top: top - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height - dy ;
var newTop = top + dy;
setState(() {
if (newHeight > 10 && newTop >= 0 ) {
height = newHeight;
top = newTop;
}
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
// top right
if (_isSelected && (width > 10 && height > 10))
Positioned(
top: top - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width + dx;
var newHeight = newWidth * aspectRatio ;
setState(() {
if (newHeight > 10 && newWidth > 10) {
top = top + (height - newHeight);
height = newHeight;
width = newWidth;
}
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
//left mid
if (_isSelected && (width > 10 && height > 10))
Positioned(
top: top + height / 2 - ballDiameter/2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth =width - dx;
setState(() {
if ( newWidth > 10) {
width = newWidth;
left = left + dx;
}
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
//bottom right
if (_isSelected && (width > 10 && height > 10))
Positioned(
top: top + height - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width + dx;
var newHeight = newWidth * aspectRatio ;
setState(() {
if (newHeight > 10 && newWidth > 10) {
height = newHeight;
width = newWidth;
}
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
//right mid
//bottom left
//bottom mid
if (_isSelected && (width > 10 && height > 10))
Positioned(
top: top + height - ballDiameter/2,
left: left + width /2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height + dy;
setState(() {
if (newHeight > 10 ) {
height = newHeight;
}
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
]);
}
}
this class for the manipulate the drag point for the update the position of point
class ManipulatingBall extends StatefulWidget {
ManipulatingBall(
{Key? key, required this.onDrag, required this.handlerWidget});
final Function onDrag;
final HandlerWidget handlerWidget;
@override
_ManipulatingBallState createState() => _ManipulatingBallState();
}
enum HandlerWidget { HORIZONTAL, VERTICAL }
class _ManipulatingBallState extends State<ManipulatingBall> {
late double initX;
late double initY;
_handleDrag(details) {
setState(() {
initX = details.globalPosition.dx;
initY = details.globalPosition.dy;
});
}
_handleUpdate(details) {
var dx = details.globalPosition.dx - initX;
var dy = details.globalPosition.dy - initY;
initX = details.globalPosition.dx;
initY = details.globalPosition.dy;
widget.onDrag(dx, dy);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: _handleDrag,
onPanUpdate: _handleUpdate,
child: Container(
width: ballDiameter,
height: ballDiameter,
decoration: BoxDecoration(
color: Colors.black,
shape: this.widget.handlerWidget == HandlerWidget.VERTICAL
? BoxShape.circle
: BoxShape.rectangle,
),
),
);
}
}
