Skip to content

Instantly share code, notes, and snippets.

@jazzbpn
Created June 17, 2021 08:03
Show Gist options
  • Save jazzbpn/9ac1cd5ccea543dc3c16c0c20afdddec to your computer and use it in GitHub Desktop.
Save jazzbpn/9ac1cd5ccea543dc3c16c0c20afdddec to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
class ResizebleWidget extends StatefulWidget {
final Widget child;
final String widgetId;
final Size size;
final bool editMode, doubleTapped;
final GestureTapCallback onSingleTapWidget, onDoubleTapWidget;
ResizebleWidget(
{this.child,
this.widgetId,
this.size,
this.editMode,
this.doubleTapped,
this.onSingleTapWidget,
this.onDoubleTapWidget});
@override
_ResizebleWidgetState createState() => _ResizebleWidgetState();
}
const ballDiameter = 25.0;
class _ResizebleWidgetState extends State<ResizebleWidget> {
double top = 0;
double left = 0;
double height = 0;
double width = 0;
bool editable;
double rotateAngle = 0;
@override
void initState() {
height = widget.size.height;
width = widget.size.width;
super.initState();
}
void onDrag(double dx, double dy) {
var newHeight = height + dy;
var newWidth = width + dx;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
});
}
showBoxDecoration() {
return BoxDecoration(
border: Border.all(
color: editable == true ? Colors.lightBlue : Colors.transparent,
width: editable == true ? 1 : 0,
),
);
}
@override
Widget build(BuildContext context) {
editable = widget.editMode;
return Transform.rotate(
angle: rotateAngle,
child: Stack(
children: <Widget>[
Positioned(
top: top,
left: left,
child: GestureDetector(
onTap: widget.onSingleTapWidget,
child: Container(
decoration: showBoxDecoration(),
height: height,
width: width,
child: widget.child,
),
),
),
// center center
editable && widget.doubleTapped == false
? Positioned(
top: top, // look 20 form transparent draggable widget
left: left,
child: InkWell(
onDoubleTap: () {
widget.onDoubleTapWidget();
},
child: ManipulatingBall(
height: height,
width: width,
color: Colors.red.withOpacity(0.6),
onDrag: (dx, dy, details) {
setState(() {
top = top + dy;
left = left + dx;
});
},
),
),
)
: Container(),
// top left
editable
? Positioned(
top: top - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var mid = (dx + dy) / 2;
var newHeight = height - 2 * mid;
var newWidth = width - 2 * mid;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top + mid;
left = left + mid;
});
},
),
)
: Container(),
// top middle
editable
? Positioned(
top: top - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var newHeight = height - dy;
setState(() {
height = newHeight > 0 ? newHeight : 0;
top = top + dy;
});
},
),
)
: Container(),
// top right
editable
? Positioned(
top: top - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var mid = (dx + (dy * -1)) / 2;
var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
)
: Container(),
// center right
editable
? Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var newWidth = width + dx;
setState(() {
width = newWidth > 0 ? newWidth : 0;
});
},
),
)
: Container(),
// bottom right
editable
? Positioned(
top: top + height - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var mid = (dx + dy) / 2;
var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
)
: Container(),
// bottom center
editable
? Positioned(
top: top + height - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var newHeight = height + dy;
setState(() {
height = newHeight > 0 ? newHeight : 0;
});
},
),
)
: Container(),
// bottom left
editable
? Positioned(
top: top + height - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var mid = ((dx * -1) + dy) / 2;
var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
)
: Container(),
//left center
editable
? Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy, details) {
var newWidth = width - dx;
setState(() {
width = newWidth > 0 ? newWidth : 0;
left = left + dx;
});
},
),
)
: Container(),
// bottom center center to Rotate-resizable-widget
editable
? Positioned(
top: top + height + ballDiameter,
left: left + width / 2 - ballDiameter / 2,
child: Stack(
children: [
Icon(
Icons.refresh,
color: Colors.black,
size: 40,
),
ManipulatingBall(
onDrag: (dx, dy, details) {
final touchPositionFromCenter = details.localPosition;
setState(
() {
rotateAngle = touchPositionFromCenter.direction;
print('Rotate--> ' + rotateAngle.toString());
},
);
},
),
],
))
: Container(),
],
),
);
}
}
class ManipulatingBall extends StatefulWidget {
ManipulatingBall({Key key, this.onDrag, this.height, this.color, this.width});
final Function onDrag;
final double height, width;
final Color color;
@override
_ManipulatingBallState createState() => _ManipulatingBallState();
}
class _ManipulatingBallState extends State<ManipulatingBall> {
double initX;
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, details);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onPanStart: _handleDrag,
onPanUpdate: _handleUpdate,
child: Container(
width: widget.width == null ? ballDiameter : widget.width,
height: widget.height == null ? ballDiameter : widget.height,
decoration: BoxDecoration(
color: widget.color == null
? Colors.blue.withOpacity(0.5)
: widget.color,
shape: widget.width == null ? BoxShape.circle : BoxShape.rectangle,
),
),
);
}
}
@jazzbpn
Copy link
Author

jazzbpn commented Jun 17, 2021

I want the end result like this https://streamable.com/faq9ia.
After resizing widget

  1. rotation should work from center and
  2. the resize pointer should work fine.

Please note after using FooResizer() I keep getting same result like https://streamable.com/oogp5f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment