如何让广场响应手势探测器 围绕一个圆圈旋转方块。顺时针转动它应该给 从0到360的正增加和逆时针应该减少 360到0.但是这里它增加到超过360并且也低于0进入 减去值。对阻力的反应是不可预测的。
只有在IT检测到手势而不是圆圈时,方块才会旋转 背后。
即使这是解决问题的方法,我也不知道。任何帮助都会非常 非常感激。我已经在这几天了。
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
runApp(new MyRotateApp());
}
class MyRotateApp extends StatefulWidget {
@override
MyRotateAppState createState() {
return new MyRotateAppState();
}
}
class MyRotateAppState extends State<MyRotateApp> {
double angleDelta;
String strDialAngle;
@override
void initState() {
angleDelta = -90.0; //start from top position
strDialAngle = 'Angle Text';
super.initState();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(title: new Text('ROTATE Square')),
body: new Center(
child: new Stack(alignment: Alignment.center,
children: <Widget>[
new Container(
height: 350.0,
decoration: new BoxDecoration(
color: Colors.blueGrey, shape: BoxShape.circle),
),
/// position the square
new MyRadialPosition(
radius: 130.0,
angle: angleDelta * PI / 180.0,
/// Gesture Detector
child: new GestureDetector(
onVerticalDragUpdate: _onVerticalDragUpdate,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
child: new Container(
width: 45.0,
height: 45.0,
color: Colors.green,
),
)),
/// update text based on angle value of rotation of square
new Padding(
padding: const EdgeInsets.only(bottom: 80.0),
child: new Text('$strDialAngle',
style: new TextStyle(fontSize: 25.0,color: Colors.white),),
),
],
),
),
));
}
void _onVerticalDragUpdate(DragUpdateDetails details) {
angleDelta = angleDelta + (details.delta.dy).roundToDouble();
strDialAngle = 'VERTICAL Drag : ${angleDelta + 90.0}';
setState((){});
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
angleDelta = angleDelta + (details.delta.dx).roundToDouble();
strDialAngle = 'Horizontal Drag : ${angleDelta + 90.0}';
setState((){});
}
}
class MyRadialPosition extends StatelessWidget {
final double radius;
final double angle;
final Widget child;
MyRadialPosition({this.radius, this.angle, this.child});
@override
Widget build(BuildContext context) {
final x = radius * cos(angle);
final y = radius * sin(angle);
return new Transform(
transform: new Matrix4.translationValues(x, y, 0.0),
child: child,);
}
}
// for adding to the above Stack RadialDragGestureDetector
new MyRadialPosition(radius: 170.0,
angle: angleDelta * PI / 180.0,
child: new RadialDragGestureDetector(
onRadialDragUpdate: _onRadialDragUpdate,
child: new Container(
width: 45.0,
height: 45.0,
color: Colors.amber,
),
),
),
_onRadialDragUpdate(PolarCoord updateCoord) {
setState((){
angleDelta = (updateCoord.angle).roundToDouble();
print('updateCoord.angle : ${(updateCoord.angle).roundToDouble()}');
});
}
答案 0 :(得分:1)
您可以使用fluttery package。它有radial drag gesture detector。
child: new RadialDragGestureDetector(
onRadialDragStart: _onRadialDragStart,
onRadialDragUpdate: _onRadialDragUpdate,
onRadialDragEnd: _onRadialDragEnd,
child: new ...
并且听众在开始和更新时获得PolarCoord
,因此您可以看到弧度。
你没有提及你是做一两个手指手势,所以如果这有帮助,请告诉我
答案 1 :(得分:1)
您可以使用onPanUpdate。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math';
class MyRotateApp extends StatefulWidget {
@override
MyRotateAppState createState() {
return new MyRotateAppState();
}
}
class MyRotateAppState extends State<MyRotateApp> {
double angleDelta;
String strDialAngle;
@override
void initState() {
angleDelta = -90.0; //start from top position
strDialAngle = 'Angle Text';
super.initState();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(title: new Text('ROTATE Square')),
body: new Center(
child: new Stack(alignment: Alignment.center,
children: <Widget>[
new Container(
height: 260.0,
width: 260.0,
decoration: new BoxDecoration(
color: Colors.blueGrey, shape: BoxShape.circle),
),
/// position the square
new MyRadialPosition(
radius: 130.0,
angle: angleDelta * 3.142 / 180.0,
/// Gesture Detector
child: new GestureDetector(
onPanUpdate: _onPanUpdate,
// onVerticalDragUpdate: _onVerticalDragUpdate,
// onHorizontalDragUpdate: _onHorizontalDragUpdate,
child: new Container(
width: 45.0,
height: 45.0,
color: Colors.green,
),
)),
/// update text based on angle value of rotation of square
new Padding(
padding: const EdgeInsets.only(bottom: 80.0),
child: new Text('$strDialAngle',
style: new TextStyle(fontSize: 25.0,color: Colors.white),),
),
],
),
),
));
}
void _onVerticalDragUpdate(DragUpdateDetails details) {
angleDelta = angleDelta + (details.delta.dy).roundToDouble();
strDialAngle = 'VERTICAL Drag : ${angleDelta + 90.0}';
setState((){});
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
angleDelta = angleDelta + (details.delta.dx).roundToDouble();
strDialAngle = 'Horizontal Drag : ${angleDelta + 90.0}';
setState((){});
}
//use onPanUpdate here
void _onPanUpdate(DragUpdateDetails details) {
Offset center = Offset(130.0, 130.0);
var a = (details.delta.dx) - center.dx;
var b = center.dy - (details.delta.dy);
angleDelta = angleDelta + atan2(b, a);
setState(() {
});
}
}
class MyRadialPosition extends StatelessWidget {
final double radius;
final double angle;
final Widget child;
MyRadialPosition({this.radius, this.angle, this.child});
@override
Widget build(BuildContext context) {
final x = radius * cos(angle);
final y = radius * sin(angle);
return new Transform(
transform: new Matrix4.translationValues(x, y, 0.0),
child: child,);
}
}
答案 2 :(得分:1)
您可以在panUpdate
和panEnd
上进行简单的计算:
_panUpdateHandler(DragUpdateDetails d) {
/// Pan location on the wheel
bool onTop = d.localPosition.dy <= radius;
bool onLeftSide = d.localPosition.dx <= radius;
bool onRightSide = !onLeftSide;
bool onBottom = !onTop;
/// Pan movements
bool panUp = d.delta.dy <= 0.0;
bool panLeft = d.delta.dx <= 0.0;
bool panRight = !panLeft;
bool panDown = !panUp;
/// Absolute change on axis
double yChange = d.delta.dy.abs();
double xChange = d.delta.dx.abs();
/// Directional change on wheel
double verticalRotation = (onRightSide && panDown) || (onLeftSide && panUp)
? yChange
: yChange * -1;
double horizontalRotation =
(onTop && panRight) || (onBottom && panLeft) ? xChange : xChange * -1;
// Total computed change
double rotationalChange = verticalRotation + horizontalRotation;
double _value = degree + (rotationalChange / 5);
setState(() {
degree = _value > 0 ? _value : 0;
ctrl.value = degree;
});
}
在平底锅上
_panEndHandler(DragEndDetails d) {
ctrl
.animateTo(roundToBase(degree.roundToDouble(), 10),
duration: Duration(milliseconds: 551), curve: Curves.easeOutBack)
.whenComplete(() {
setState(() {
degree = roundToBase(degree.roundToDouble(), 10);
});
});
}
然后将它们附加到手势检测器上
GestureDetector draggableWheel = GestureDetector(
onPanUpdate: _panUpdateHandler,
onPanEnd: _panEndHandler,
child: Stack(
children: [
AnimatedBuilder(
animation: ctrl,
builder: (ctx, w) {
return Transform.rotate(
angle: degreeToRadians(ctrl.value),
child: wheelContainer,
);
},
),
Container(
width: wheelSize,
height: wheelSize / 2,
margin: const EdgeInsets.only(top: 30),
child: Center(
child: Padding(
padding: EdgeInsets.only(top: this.longNeedleHeight + 10),
child: Image(
image: NetworkImage(
'https://d20nqim3b55fln.cloudfront.net/images/ic_needle_light.png'),
),
),
),
),
Container(
width: wheelSize,
height: wheelSize,
child: CustomPaint(
painter: WheelDecoration(context),
),
),
],
),
);
以下是完整的示例供您参考: 密码笔链接:https://codepen.io/godwinvc/pen/oNxrOeX
iframe {
display:block;
vertical-align:top;
width: 600px;
height: 800px;
}
<iframe style="overflow-y: auto; -webkit-overflow-scrolling: touch; display:block; vertical-align:top;" src="https://codepen.io/godwinvc/full/oNxrOeX"></iframe>