Flutter--捕捉手势的弧度和角度

150 阅读1分钟

import 'package:flutter/material.dart';

class GestureAngleView extends StatelessWidget{

final double angel;

final Function(double angel, bool end) onChanged; final List Function(BuildContext context, Size size, double radian)buildChildren;

const GestureAngleView(this.angel, this.onChanged, this.buildChildren);

@override Widget build(BuildContext context) { return GestureView( builder: (context, size) { return Stack( alignment:Alignment.center , children: buildChildren(context, size, angel / 180 * pi), ); }, onChanged: (point, size, isEnd) { turn(point, size, isEnd); }, ); }

void turn(Offset point, Size size, bool isEnd){ var radian = getRadians(size.center(Offset.zero), point); var angel = getAngel(radian); onChanged(angel, isEnd); }

double getRadius(Offset point, Offset center) { return sqrt(pow((point.dx - center.dx), 2) + pow(point.dy - center.dy, 2)); }

double getRadians(Offset center, Offset point) { var a = point.dx - center.dx; var b = center.dy - point.dy; double radians = atan2(b, a); return radians < 0 ? -radians : 2 * pi - radians; }

double getAngel(double radian) { if(radian >= 2 * pi) { radian -= 2 * pi; } if(radian < 0) { radian += 2 * pi; }

return (radian / pi) * 180;

}

}

class GestureView extends StatefulWidget {

final Function(Offset point, Size size, bool end) onChanged; final Widget Function(BuildContext context, Size size) builder;

const GestureView({@required this.builder, @required this.onChanged, Key key}) : super(key: key);

@override State createState() => _GestureState();

} class _GestureState extends State {

Offset point; Size size;

@override Widget build(BuildContext context) { return LayoutBuilder(builder: (BuildContext ctx, BoxConstraints constraints) { double width = constraints.maxWidth; double height = constraints.maxHeight;

  size = Size(width, height);

  return Center(child: GestureDetector(
    onHorizontalDragDown: (DragDownDetails details) => turn(details.globalPosition, details.localPosition),
    onHorizontalDragUpdate: (DragUpdateDetails details) => turn(details.globalPosition,  details.localPosition),
    onHorizontalDragEnd: (DragEndDetails details) => widget.onChanged(point, size, true),
    onVerticalDragDown: (DragDownDetails details) => turn(details.globalPosition,  details.localPosition),
    onVerticalDragUpdate: (DragUpdateDetails details) => turn(details.globalPosition,  details.localPosition),
    onVerticalDragEnd: (DragEndDetails details) => widget.onChanged(point, size, true),
    child: SizedBox(
      width: width,
      height: height,
      child: widget.builder(context, size),
    ),
  ),);
},);

}

void turn(Offset globalPosition, Offset localPosition){ point = localPosition; widget.onChanged(point, size, false); }

}