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(() {});
}
}
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(() {});
}
}