How to calculate the angle of lines drawn in flutter? Need to find the angle between two lines

Viewed 531

I'm working on a paint like application where lines and shapes can be drawn using tapped coordinates. I need to get the angle or degree of the lines drawn in my canvas. Have used CustomPaint to draw the lines and XGestureDetector to get the coordinates onTap.

enter image description here

I Need to achieve the above.

Here's my code,

class LandingScreen extends State<MyApp> {
  LandingScreen(List<List<Offset>> connectionList);

  @override
  void initState() {
    XGesture();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    late List<List<Offset>> _connectionList;
    _connectionList = [[Offset(104.0, 242.6), Offset(101.4, 559.3)], [Offset(238.9, 238.6), Offset(229.8, 440.4)]];

    String dropdownvalue = 'Square';
    var items = ['Square', ' Circle ', ' Rectangle ', ' Circle ',];

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body:
        XGesture(),
      ),
    );
  }
}

class XGesture extends StatefulWidget {
  late List<List<Offset>> connectionListRedo = [];

  @override
  _XGestureState createState() => _XGestureState();
}

class _XGestureState extends State<XGesture> {
  late MoveEvent pos1;
  late MoveEvent pos2;
  late List<List<Offset>> _connectionList;
  late List<List<Offset>> connectionListRedo1;

  _XGestureState();

  @override
  void initState() {
    onMoveStart;
    pos1 = MoveEvent(Offset(0.0, 0.0), Offset(0.0, 0.0), 0);
    pos2 = MoveEvent(Offset(0.0, 0.0), Offset(0.0, 0.0), 0);
    _connectionList = [];
    onMoveEnd;
    LandingScreen(_connectionList);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    String dropdownvalue = 'Square';
    var items = [
      'Square',
      ' Circle ',
      ' Rectangle ',
      ' Circle ',
    ];
    String dropdownvalue1 = 'Teams';
    var items1 = [
      'Teams',
      ' Sluggers ',
      ' Lakes ',
      ' Add More ',
    ];

    final x = Angle.degrees(180.0);
    debugPrint('Angle of x : ${x.degrees}');

    return XGestureDetector(
      child: Material(
        color: Colors.black87,
        child: Center(
            child: CustomPaint(
          painter: LinePainter(pos1.localPos, pos2.localPos, _connectionList),
          child:SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                Container(
                  padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
                  decoration:BoxDecoration(
                      borderRadius:BorderRadius.circular(5),
                    border: Border.all(color: Colors.green, width: 4),
                    color: Color(0xDC063280),
                  ),
                  child: TextButton.icon(
                      label: const Text('Undo', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
                      icon: Icon(Icons.undo, color: Colors.white,),
                      onPressed: () {
                        widget.connectionListRedo.add(_connectionList.last);
                        debugPrint('Not Removed Offset List value: ${widget.connectionListRedo}');
                        _connectionList.removeLast();
                        debugPrint('Removed Offset List value: $_connectionList');
                        print('Pressed Undo btn');
                      }),
                ),
        ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                    padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
                    decoration:BoxDecoration(
                        borderRadius:BorderRadius.circular(5),
                        border: Border.all(color: Colors.green, width: 4),
                        color: Color(0xDC063280),
                    ),
                    child: TextButton.icon(
                        label: const Text('Redo', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
                        icon: Icon(Icons.redo, color: Colors.white,),
                        onPressed: () {
                          debugPrint('Not Removed Offset List value in Redo: ${widget.connectionListRedo}');
                          _connectionList.add(widget.connectionListRedo.last);
                          widget.connectionListRedo.removeLast();
                          debugPrint('Retrieved Offset value Redo: $_connectionList');
                          print('Pressed Undo btn');
                        }),
                  ),
                ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                      padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
                      decoration:BoxDecoration(
                        borderRadius:BorderRadius.circular(5),
                        border: Border.all(color: Colors.green, width: 4),
                        color: Color(0xDC063280),
                      ),
                      child:
                      TextButton.icon(
                          label: const Text('Line', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
                          icon: Icon(Icons.create, color: Colors.white),
                          onPressed: () {
                            print('Pressed Line btn');
                          })
                  ),
                ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                    padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 3.5,right: 0.0),
                      decoration:BoxDecoration(
                          borderRadius:BorderRadius.circular(5),
                        border: Border.all(color: Colors.green, width: 4),
                        color: Color(0xDC063280),
                      ),
                      child:
                      DropdownButton(
                        icon: const Icon(Icons.arrow_drop_down, color: Colors.white, size: 30,),
                        style: const TextStyle(
                          color: Colors.white,
                          fontSize: 20,
                        ),
                        value: dropdownvalue,
                        dropdownColor: Colors.redAccent,
                        items: items.map((String items) {
                        return DropdownMenuItem(child: Text(items),
                        value: items,
                        );
                      }).toList(),
                        onChanged: (String? value){
                        setState(() {
                          dropdownvalue = value!;
                        });
                        },
                      ),
                  ),
                ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                    padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
                    decoration:BoxDecoration(
                        borderRadius:BorderRadius.circular(5),
                      border: Border.all(color: Colors.green, width: 4),
                      color: Color(0xDC063280),
                    ),
                    child: TextButton.icon(
                        label: const Text('My Videos', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
                        icon: Icon(Icons.image, color: Colors.white,),
                        onPressed: () {
                          print('Pressed Video btn');
                        }),
                  ),
                ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                      padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
                      decoration:BoxDecoration(
                          borderRadius:BorderRadius.circular(5),
                        border: Border.all(color: Colors.green, width: 4),
                        color: Color(0xDC063280),

                      ),
                      child:
                      TextButton.icon(
                          label: const Text('Notifications', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
                          // icon: Icon(Icons.align_vertical_center_sharp, color: Colors.white),
                          icon: Icon(Icons.notifications, color: Colors.white),

                          onPressed: () {
                            print('Pressed Notifications btn');
                          })
                  ),
                ),
                Align(
                  alignment: FractionalOffset.bottomLeft,
                  child:
                  Container(
                    padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 3.5,right: 0.0),
                    decoration:BoxDecoration(
                        borderRadius:BorderRadius.circular(5),
                        border: Border.all(color: Colors.redAccent, width: 4),
                        color:Colors.black87
                    ),
                    child:
                    DropdownButton(
                      icon: const Icon(Icons.arrow_drop_down, color: Colors.white, size: 30,),
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 20,
                      ),
                      value: dropdownvalue1,
                      dropdownColor: Colors.redAccent,
                      items: items1.map((String items) {
                        return DropdownMenuItem(child: Text(items),
                          value: items,
                        );
                      }).toList(),
                      onChanged: (String? value){
                        setState(() {
                          dropdownvalue1 = value!;
                        });
                      },
                    ),
                  ),
                ),

              ],
            ),
          ),
        )),
      ),
      doubleTapTimeConsider: 300,
      longPressTimeConsider: 350,
      onTap: onTap,
      onMoveStart: onMoveStart,
      onMoveEnd: onMoveEnd,
      onMoveUpdate: onMoveUpdate,
      onScaleStart: onScaleStart,
      onScaleUpdate: onScaleUpdate,
      onScaleEnd: onScaleEnd,
      bypassTapEventOnDoubleTap: false,
    );

  }

  void onScaleEnd() {
    setLastEventName('onScaleEnd');
    print('onScaleEnd');
  }

  void onScaleStart(initialFocusPoint) {
    setLastEventName('onScaleStart');
    print('onScaleStart - initialFocusPoint: ' + initialFocusPoint.toString());
  }

  void onLongPress(pointer, localPos, position) {
    setLastEventName('onLongPress');
    print('onLongPress - pos: ' + localPos.toString());
  }

  void onDoubleTap(localPos, position) {
    setLastEventName('onDoubleTap');
    print('onDoubleTap - pos: ' + localPos.toString());

    _connectionList.removeLast();
  }

  void onTap(event) {
    setLastEventName('onTap');
    print('onTap - pos: ' + event.localPos.toString());
  }

  Future<void> onMoveUpdate(MoveEvent event) async {
    setLastEventName('onMoveUpdate');
    print('onMoveUpdate - pos: ${event.localPos} delta: ${event.delta}');
  }

  void onMoveStart(localPos) {
    setLastEventName('onMoveStart');
    print('onMoveStart - pos: $localPos');
    pos1 = localPos;
    debugPrint('pos1 Local pos: ${pos1.localPos}');
    debugPrint('pos1 delta pos: ${pos1.delta}');
  }

  void onMoveEnd(localPos) {
    setLastEventName('onMoveEnd');
    print('onMoveEnd - pos: $localPos');
    pos2 = localPos;
    debugPrint('pos2 Local pos: ${pos2.localPos}');
    debugPrint('position1 ${pos1.localPos}, position2 ${pos2.localPos}');

    List<Offset> _offsets = [];
    _offsets.add(pos1.localPos);
    _offsets.add(pos2.localPos);
    _connectionList.add(_offsets);

    widget.connectionListRedo = [];

    debugPrint('Offset List value: ${_offsets}, List: $_connectionList');
    LinePainter(pos1.localPos, pos2.localPos, _connectionList);
  }

  void onScaleUpdate(ScaleEvent event) {
    setLastEventName('onScaleUpdate');
    print(
        'onScaleUpdate - changedFocusPoint:  ${event.focalPoint} ; scale: ${event.scale} ;Rotation: ${event.rotationAngle}');
  }
}

Since I'm new to Flutter, there'll be some unwanted code. Please ignore those.

0 Answers
Related