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,
),
),
);
}
}
@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