Skip to content

Instantly share code, notes, and snippets.

@kherel
Created April 6, 2020 19:23
Show Gist options
  • Save kherel/19ecf4fc9818592fa2b37a6c69bbca55 to your computer and use it in GitHub Desktop.
Save kherel/19ecf4fc9818592fa2b37a6c69bbca55 to your computer and use it in GitHub Desktop.
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text Overflow Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Demo(),
),
);
}
}
class Demo extends StatefulWidget {
@override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
@override
Widget build(BuildContext context) {
return Container(
child: ResizebleWidget(
child: Text(
'''I've just did simple prototype to show main idea.
1. Draw size handlers with container;
2. Use GestureDetector to get new variables of sizes
3. Refresh the main container size.''',
),
),
);
}
}
class ResizebleWidget extends StatefulWidget {
ResizebleWidget({this.child});
final Widget child;
@override
_ResizebleWidgetState createState() => _ResizebleWidgetState();
}
const ballDiameter = 30.0;
class _ResizebleWidgetState extends State<ResizebleWidget> {
double height = 400;
double width = 200;
double top = 0;
double left = 0;
double zoom = 1;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: top,
left: left,
child: Transform.scale(
scale: zoom,
child: Container(
height: height,
width: width,
color: Colors.red[100],
child: widget.child,
),
),
),
// top left
Positioned(
top: top - (height * zoom - height) / 2 - ballDiameter / 2,
left: left - (width * zoom - width) / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = dx + dy;
var zoomRate = (width + height - mid) / (width + height);
setState(() {
zoom = zoom * pow(zoomRate, 2);
});
},
),
),
// top middle
Positioned(
top: top - (height * zoom - height) / 2 - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height - dy;
setState(() {
height = newHeight > 0 ? newHeight : 0;
top = top + dy;
});
},
),
),
// top right
Positioned(
top: top - (height * zoom - height) / 2 - ballDiameter / 2,
left: left + (width * zoom - width) / 2 + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (-dx + dy);
var zoomRate = (width + height - mid) / (width + height);
setState(() {
zoom = zoom * pow(zoomRate, 2);
});
},
),
),
// center right
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + (width * zoom - width) / 2 + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width + dx;
setState(() {
width = newWidth > 0 ? newWidth : 0;
});
},
),
),
// bottom right
Positioned(
top: top + (height * zoom - height) / 2 + height - ballDiameter / 2,
left: left + (width * zoom - width) / 2 + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (-dx - dy);
var zoomRate = (width + height - mid) / (width + height);
setState(() {
zoom = zoom * pow(zoomRate, 2);
});
},
),
),
// bottom center
Positioned(
top: top + (height * zoom - height) / 2 + height - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height + dy;
setState(() {
height = newHeight > 0 ? newHeight : 0;
});
},
),
),
// bottom left
Positioned(
top: top + (height * zoom - height) / 2 + height - ballDiameter / 2,
left: left - (width * zoom - width) / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (dx - dy);
var zoomRate = (width + height - mid) / (width + height);
setState(() {
zoom = zoom * pow(zoomRate, 2);
});
},
),
),
//left center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left - (width * zoom - width) / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width - dx;
setState(() {
width = newWidth > 0 ? newWidth : 0;
left = left + dx;
});
},
),
),
// center center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
setState(() {
top = top + dy;
left = left + dx;
});
},
),
),
],
);
}
}
class ManipulatingBall extends StatefulWidget {
ManipulatingBall({Key key, this.onDrag});
final Function onDrag;
@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);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: _handleDrag,
onPanUpdate: _handleUpdate,
child: Container(
width: ballDiameter,
height: ballDiameter,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.5),
shape: BoxShape.circle,
),
),
);
}
}
@jazzbpn
Copy link

jazzbpn commented Jun 17, 2021

Create positioned widget to rotate the resizable widget. This widget rotates but it miss some properties like rotate from exact center and other which is shown in the video: https://streamable.com/oogp5f

    **// bottom center center to Rotate-resizable-widget**
    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());
                            },
                          );
                        },
                      ),
                    ],
                  )) 
          ......

@kherel
Copy link
Author

kherel commented Jun 18, 2021

cannot open the video link

@jazzbpn
Copy link

jazzbpn commented Jun 22, 2021

I am trying to rotate and drag this widget. But getting the problem while rotating. I am trying to make the make the widget like https://streamable.com/ko8m53 . But it's not working. Please help!

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