2

i try to rotate the widget and then try to move around, it moves into different direction.

I'm realize, I need another calculation to normalize the position when its move, with condition rotate more than zero , but I don't know how, if anyone can help, thank you this is my code.

import 'package:flutter/material.dart';

void main() {
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      home: const TestingDesign2(),
    );
  }
}

class TestingDesign2 extends StatefulWidget {
  const TestingDesign2({super.key});

  @override
  State<TestingDesign2> createState() => _TestingDesign2State();
}

class _TestingDesign2State extends State<TestingDesign2> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Testing")),
        body: Container(
          color: Colors.blueAccent.withOpacity(0.5),
          child: Stack(
            alignment: Alignment.center,
            // clipBehavior: Clip.none,
            children: [ItemTesting()],
          ),
        ));
  }
}

class ItemTesting extends StatefulWidget {
  const ItemTesting({super.key});

  @override
  State<ItemTesting> createState() => _ItemTestingState();
}

class _ItemTestingState extends State<ItemTesting> {
  double rotation = 0;
  Size size = Size(300, 300);
  Offset position = Offset(10, 10);
  double offsetAngle = 0;
  bool isRotate = false;

  @override
  Widget build(BuildContext context) {
    return _Item();
  }

  Widget _Item() {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Transform.rotate(
        angle: rotation,
        child: SizedBox(
          height: size.height,
          width: size.width,
          child: Stack(
            children: [
              GestureDetector(
                onPanStart: onPanStart,
                onPanUpdate: onPanUpdate,
                onPanEnd: (details) {
                  isRotate = false;
                },
                onPanCancel: () {
                  isRotate = false;
                },
                child: Container(
                  color: Colors.red,
                  height: size.height,
                  width: size.width,
                ),
              ),
              IgnorePointer(
                child: Align(
                  alignment: Alignment.topRight,
                  child: ClipOval(
                      child: Container(
                    height: 25,
                    width: 25,
                    color: Colors.blue,
                  )),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  onPanStart(details) {
    Offset centerOfGestureDetector = Offset(size.width / 2, size.height / 2);
    final touchPositionFromCenter =
        details.localPosition - centerOfGestureDetector;
    offsetAngle = touchPositionFromCenter.direction - rotation;
    // top right
    if (details.localPosition.dx > (size.width - 25) &&
        details.localPosition.dy <= 25) {
      isRotate = true;
    }
  }

  onPanUpdate(details) {
    if (isRotate) {
      Offset centerOfGestureDetector = Offset(size.width / 2, size.height / 2);
      final touchPositionFromCenter =
          details.localPosition - centerOfGestureDetector;
      // print(touchPositionFromCenter.direction * 180 / math.pi);

      rotation = touchPositionFromCenter.direction - offsetAngle;
    } else {
      position = new Offset(
          position.dx + details.delta.dx, position.dy + details.delta.dy);
    }
    setState(() {});
  }
}

enter image description here

https://dartpad.dev/?id=1403cd7c7a121a7b26d6b6c3ab422cf0

mamena tech
  • 496
  • 5
  • 16
  • Can you please explain what do you mean by " with condition rotate more than zero?" not able to catch this point. Also i didn't notice in the Dartpad link – Sanketh B. K Sep 25 '22 at 09:28
  • 1
    @SankethB.K the point is, after rotate the widget and then try to move around, it moves into different direction. after rotate means angle not zero anymore, have you try rotate before move the widget? – mamena tech Sep 25 '22 at 11:21
  • Understood, i'll look into it – Sanketh B. K Sep 25 '22 at 18:07
  • Couldn't solve it, seems like there is a package for it, can you try it https://github.com/PratikKargathra/floating-widget/blob/main/drs_widget_code.dart – Sanketh B. K Sep 25 '22 at 19:34
  • @SankethB.K alright, thanks, already found my answer. the answer below. – mamena tech Sep 27 '22 at 07:45

1 Answers1

1

Finally, I managed to make a widget that can be rotated and moved without moving in the wrong direction after rotated.

this is the code

import 'package:flutter/material.dart';

void main() {
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      home: const TestingDesign2(),
    );
  }
}



class TestingDesign2 extends StatefulWidget {
  const TestingDesign2({super.key});

  @override
  State<TestingDesign2> createState() => _TestingDesign2State();
}

class _TestingDesign2State extends State<TestingDesign2> {
  Size size = Size(200, 200);

  var keyItem = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Testing design 2")),
        body: Container(
          color: Colors.blueAccent.withOpacity(0.5),
          // key: keyContainer,
          child: Stack(
            alignment: Alignment.center,
            // clipBehavior: Clip.none,
            children: [ItemTesting(key: keyItem, keyItem: keyItem)],
          ),
        ));
  }
}

class ItemTesting extends StatefulWidget {
  var keyItem;
  ItemTesting({super.key, required this.keyItem});

  @override
  State<ItemTesting> createState() => _ItemTestingState();
}

class _ItemTestingState extends State<ItemTesting> {
  double rotation = 0;
  Size size = Size(300, 300);
  Offset position = Offset(10, 10);
  double offsetAngle = 0;
  bool isRotate = false;

  @override
  Widget build(BuildContext context) {
    return _Item();
  }

  Widget _Item() {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Transform.rotate(
        angle: rotation,
        child: SizedBox(
          height: size.height,
          width: size.width,
          child: Stack(
            children: [
              GestureDetector(
                onPanStart: onPanStart,
                onPanUpdate: onPanUpdate,
                behavior: HitTestBehavior.translucent,
                onPanEnd: (details) {
                  isRotate = false;
                },
                onPanCancel: () {
                  isRotate = false;
                },
                child: Container(
                  color: Colors.red,
                  height: size.height,
                  width: size.width,
                ),
              ),
              IgnorePointer(
                child: Align(
                  alignment: Alignment.topRight,
                  child: ClipOval(
                      child: Container(
                    height: 25,
                    width: 25,
                    color: Colors.blue,
                  )),
                ),
              ),
         
            ],
          ),
        ),
      ),
    );
  }

  

  var touchPosition = Offset.zero;
  onPanStart(DragStartDetails details) {
    Offset centerOfGestureDetector = Offset(size.width / 2, size.height / 2);
    final touchPositionFromCenter =
        details.localPosition - centerOfGestureDetector;
    offsetAngle = touchPositionFromCenter.direction - rotation;

    final RenderBox referenceBox =
        widget.keyItem.currentContext.findRenderObject();
    var x = referenceBox.globalToLocal(details.globalPosition);

    touchPosition = Offset(x.dx, x.dy + 55);
    // top right
    if (details.localPosition.dx > (size.width - 25) &&
        details.localPosition.dy <= 25) {
      isRotate = true;
    }
  }

  onPanUpdate(DragUpdateDetails details) {
    if (isRotate) {
      Offset centerOfGestureDetector = Offset(size.width / 2, size.height / 2);
      final touchPositionFromCenter =
          details.localPosition - centerOfGestureDetector;

      rotation = touchPositionFromCenter.direction - offsetAngle;
    } else {
      var positionG = position + details.globalPosition;
      var positiong2 = positionG - touchPosition;
      position = (positiong2 - position);
    }
    setState(() {});
  }
}
mamena tech
  • 496
  • 5
  • 16