Created
April 6, 2020 19:23
-
-
Save kherel/19ecf4fc9818592fa2b37a6c69bbca55 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | |
), | |
), | |
); | |
} | |
} |
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
cannot open the video link