hyzp_ybqx-Commit001:代码刚转换好,编译通过
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
library flutterptcontrol;
|
||||
|
||||
import 'dart:math' as MATH;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef void PtCallback(int status);
|
||||
|
||||
//pan-tilt Control
|
||||
class PtControlWidget extends StatefulWidget {
|
||||
PtControlWidget(
|
||||
{@required this.innerRadius, @required this.outerRadius, @required this.callback});
|
||||
|
||||
///内径
|
||||
final double innerRadius;
|
||||
|
||||
///外径
|
||||
final double outerRadius;
|
||||
|
||||
///点击回调
|
||||
final PtCallback callback;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _PtControlWidgetState();
|
||||
}
|
||||
}
|
||||
|
||||
class _PtControlWidgetState extends State<PtControlWidget> {
|
||||
int status = -1;
|
||||
|
||||
/*
|
||||
3.获取控件的坐标:
|
||||
RenderBox renderBox = anchorKey.currentContext.findRenderObject();
|
||||
var offset = renderBox.localToGlobal(Offset.zero);
|
||||
控件的横坐标:offset.dx
|
||||
控件的纵坐标:offset.dy
|
||||
|
||||
如果想获得控件正下方的坐标:
|
||||
RenderBox renderBox = anchorKey.currentContext.findRenderObject();
|
||||
var offset = renderBox.localToGlobal(Offset(0.0, renderBox.size.height));
|
||||
控件下方的横坐标:offset.dx
|
||||
控件下方的纵坐标:offset.dy
|
||||
————————————————
|
||||
版权声明:本文为CSDN博主「笨鸟不飞 ≧0≦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
原文链接:https://blog.csdn.net/baidu_34120295/article/details/86495861
|
||||
*/
|
||||
|
||||
//获得本组件中心点对象:Point(offset.dx, offset.dy)
|
||||
//Another exception was thrown: type 'Point<num>' is not a subtype of type 'Point<double>'
|
||||
MATH.Point getCenterPoint() {
|
||||
RenderBox renderBox = context.findRenderObject();
|
||||
//控件中心坐标:(offset.dx, offset.dy)
|
||||
var offset =
|
||||
renderBox.localToGlobal(Offset(renderBox.size.width / 2, renderBox.size.height / 2));
|
||||
print('(offset.dx, offset.dy) = (${offset.dx}, ${offset.dy})');
|
||||
return MATH.Point<num>(offset.dx.toInt(), offset.dy.toInt());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onPanDown: (details) {
|
||||
//坐标系转换
|
||||
var x = details.localPosition.dx - widget.outerRadius;
|
||||
var y = -(details.localPosition.dy - widget.outerRadius);
|
||||
|
||||
//判断点击位置是否超出范围
|
||||
var dis = MATH.Point(x, y).distanceTo(MATH.Point(0, 0));
|
||||
|
||||
/*
|
||||
计算圆周上坐标点的公式,其中圆心坐标(xo,yo),r为圆半径,α为0~2π,(x,y)为圆上的点
|
||||
x = xo + r * cos(α)
|
||||
y = yo + r * sin(α)
|
||||
|
||||
原点坐标为(0, 0),x轴向左为正,y轴向上为正,逆时针方向的8个点的弧度为
|
||||
0 π * 1/8
|
||||
1 π * 3/8
|
||||
2 π * 5/8
|
||||
3 π * 7/8
|
||||
4 π * 9/8
|
||||
5 π * 11/8
|
||||
6 π * 13/8
|
||||
7 π * 15/8
|
||||
*/
|
||||
|
||||
// dart 计算原点坐标为(0, 0),x轴向左为正,y轴向上为正,逆时针方向的8个点的坐标
|
||||
List listInnerPoint = List.generate(8, (index) {
|
||||
double _radians = MATH.pi * (index * 2 + 1) / 8;
|
||||
//print('index = $index');
|
||||
return {
|
||||
'x': MATH.cos(_radians) * widget.innerRadius,
|
||||
'y': MATH.sin(_radians) * widget.innerRadius,
|
||||
};
|
||||
});
|
||||
|
||||
// dart 计算原点坐标为(0, 0),x轴向左为正,y轴向上为正,逆时针方向的8个点的坐标
|
||||
List listOuterPoint = List.generate(8, (index) {
|
||||
double _radians = MATH.pi * (index * 2 + 1) / 8;
|
||||
//print('index = $index');
|
||||
return {
|
||||
'x': MATH.cos(_radians) * widget.outerRadius,
|
||||
'y': MATH.sin(_radians) * widget.outerRadius,
|
||||
};
|
||||
});
|
||||
|
||||
print('listInnerPoint = ${listInnerPoint}');
|
||||
print('[x, y] = [$x, $y]');
|
||||
//超出范围
|
||||
if (dis > widget.outerRadius) {
|
||||
status = -1;
|
||||
} else if (dis < widget.innerRadius) {
|
||||
//还原
|
||||
status = 8;
|
||||
} else if (x > listOuterPoint[1]['x'] ||
|
||||
(y > 0 &&
|
||||
x > listInnerPoint[1]['x'] &&
|
||||
y <
|
||||
listInnerPoint[1]['y'] +
|
||||
(x - listInnerPoint[1]['x']) / MATH.tan(MATH.pi / 8)) ||
|
||||
(y < 0 &&
|
||||
x > listInnerPoint[6]['x'] &&
|
||||
y >
|
||||
listInnerPoint[6]['y'] -
|
||||
(x - listInnerPoint[6]['x']) / MATH.tan(MATH.pi / 8))) {
|
||||
if (y > listOuterPoint[0]['y'] ||
|
||||
y > listInnerPoint[0]['y'] &&
|
||||
x <
|
||||
listInnerPoint[0]['x'] +
|
||||
(y - listInnerPoint[0]['y']) / MATH.tan(MATH.pi / 8)) {
|
||||
//右上
|
||||
status = 1;
|
||||
} else if (y > listInnerPoint[7]['y'] ||
|
||||
y > listOuterPoint[7]['y'] &&
|
||||
x >
|
||||
listInnerPoint[7]['x'] +
|
||||
(listInnerPoint[7]['y'] - y) / MATH.tan(MATH.pi / 8)) {
|
||||
//右
|
||||
status = 0;
|
||||
} else {
|
||||
//右下
|
||||
status = 7;
|
||||
}
|
||||
} else if (x > listInnerPoint[2]['x'] ||
|
||||
y > 0 &&
|
||||
x > listOuterPoint[2]['x'] &&
|
||||
y > listInnerPoint[2]['y'] + (listInnerPoint[2]['x'] - x) / MATH.tan(MATH.pi / 8) ||
|
||||
y < 0 &&
|
||||
x < listInnerPoint[5]['x'] &&
|
||||
y < listInnerPoint[5]['y'] - (listInnerPoint[5]['x'] - x) / MATH.tan(MATH.pi / 8)) {
|
||||
if (y > 0) {
|
||||
//上
|
||||
status = 2;
|
||||
} else {
|
||||
//下
|
||||
status = 6;
|
||||
}
|
||||
} else {
|
||||
if (y > listOuterPoint[3]['y'] ||
|
||||
y > listInnerPoint[3]['y'] &&
|
||||
x >
|
||||
listOuterPoint[3]['x'] -
|
||||
(y - listOuterPoint[3]['y']) / MATH.tan(MATH.pi / 8)) {
|
||||
//左上
|
||||
status = 3;
|
||||
} else if (y > listInnerPoint[4]['y'] ||
|
||||
y > listOuterPoint[4]['y'] &&
|
||||
x <
|
||||
listOuterPoint[4]['x'] +
|
||||
(listInnerPoint[4]['y'] - y) / MATH.tan(MATH.pi / 8)) {
|
||||
//左
|
||||
status = 4;
|
||||
} else {
|
||||
//左下
|
||||
status = 5;
|
||||
}
|
||||
}
|
||||
widget.callback(status);
|
||||
setState(() {});
|
||||
},
|
||||
onPanEnd: (details) {
|
||||
status = -1;
|
||||
setState(() {});
|
||||
},
|
||||
|
||||
///点击回调
|
||||
/// status == -1 超出范围
|
||||
/// status == 0 右
|
||||
/// status == 1 右上
|
||||
/// status == 2 上
|
||||
/// status == 3 左上
|
||||
/// status == 4 左
|
||||
/// status == 5 左下
|
||||
/// status == 6 下
|
||||
/// status == 7 右下
|
||||
/// status == 8 还原
|
||||
|
||||
/// color: Colors.black12
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
null == widget.callback
|
||||
? 'images/pt_background_disable.png'
|
||||
: 'images/pt_background_enable.png',
|
||||
package: 'flutterptcontrol'),
|
||||
status == 0
|
||||
? Image.asset('images/pt_right.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 1
|
||||
? Image.asset('images/pt_right_top.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 2
|
||||
? Image.asset('images/pt_top.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 3
|
||||
? Image.asset('images/pt_left_top.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 4
|
||||
? Image.asset('images/pt_left.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 5
|
||||
? Image.asset('images/pt_left_bottom.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 6
|
||||
? Image.asset('images/pt_bottom.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
status == 7
|
||||
? Image.asset('images/pt_right_bottom.png', package: 'flutterptcontrol')
|
||||
: SizedBox.shrink(),
|
||||
// status == 8
|
||||
// ? Image.asset('images/pt_center.png', package: 'flutterptcontrol')
|
||||
// : SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user