This commit is contained in:
otsmr 2025-02-10 22:31:22 +01:00
parent 645eb452c6
commit ea7b29f594
2 changed files with 61 additions and 35 deletions

View file

@ -19,8 +19,11 @@ class EmojiLayer extends StatefulWidget {
class _EmojiLayerState extends State<EmojiLayer> { class _EmojiLayerState extends State<EmojiLayer> {
double initialRotation = 0; double initialRotation = 0;
Offset initialOffset = Offset.zero; Offset initialOffset = Offset.zero;
Offset initialFocalPoint = Offset.zero;
double initialScale = 1.0; double initialScale = 1.0;
bool twoPointerWhereDown = false;
final GlobalKey _key = GlobalKey(); final GlobalKey _key = GlobalKey();
int pointers = 0;
@override @override
void initState() { void initState() {
@ -43,44 +46,68 @@ class _EmojiLayerState extends State<EmojiLayer> {
return Positioned( return Positioned(
left: widget.layerData.offset.dx, left: widget.layerData.offset.dx,
top: widget.layerData.offset.dy, top: widget.layerData.offset.dy,
child: GestureDetector( child: Listener(
onTap: () {}, onPointerUp: (details) {
onScaleStart: (details) {
// Store the initial scale and rotation
initialScale = widget.layerData.size; // Reset initial scale
initialRotation = widget.layerData.rotation;
initialOffset = widget.layerData.offset;
},
onScaleUpdate: (details) {
setState(() { setState(() {
// Update the size based on the scale factor pointers--;
if (pointers == 0) {
widget.layerData.size = initialScale * details.scale; twoPointerWhereDown = false;
}
// Update the rotation based on the rotation angle
widget.layerData.rotation = initialRotation + details.rotation;
// Update the position based on the translation
final RenderBox renderBox =
_key.currentContext?.findRenderObject() as RenderBox;
var dx = details.focalPoint.dx - (renderBox.size.width / 2);
var dy = details.focalPoint.dy - (renderBox.size.height / 2 + 34);
widget.layerData.offset = Offset(dx, dy);
}); });
}, },
onScaleEnd: (details) { onPointerDown: (details) {
// Optionally, you can handle the end of the scale gesture here setState(() {
pointers++;
});
}, },
child: Transform.rotate( child: GestureDetector(
key: _key, onScaleStart: (details) {
angle: widget.layerData.rotation, // Store the initial scale and rotation
child: Container( initialScale = widget.layerData.size; // Reset initial scale
padding: const EdgeInsets.all(34), initialRotation = widget.layerData.rotation;
color: Colors.transparent, initialOffset = widget.layerData.offset;
child: Text( initialFocalPoint =
widget.layerData.text.toString(), Offset(details.focalPoint.dx, details.focalPoint.dy);
style: TextStyle(
fontSize: widget.layerData.size, setState(() {});
},
onScaleUpdate: (details) {
if (twoPointerWhereDown == true && details.pointerCount != 2) {
return;
}
setState(() {
// Update the size based on the scale factor
twoPointerWhereDown = details.pointerCount >= 2;
widget.layerData.size = initialScale * details.scale;
// Update the rotation based on the rotation angle
widget.layerData.rotation = initialRotation + details.rotation;
// Update the position based on the translation
var dx = (initialOffset.dx) +
(details.focalPoint.dx - initialFocalPoint.dx);
var dy = (initialOffset.dy) +
(details.focalPoint.dy - initialFocalPoint.dy);
// var dy = details.focalPoint.dy - (renderBox.size.height / 2 + 34);
widget.layerData.offset = Offset(dx, dy);
});
},
onScaleEnd: (details) {
// Optionally, you can handle the end of the scale gesture here
},
child: Transform.rotate(
key: _key,
angle: widget.layerData.rotation,
child: Container(
padding: const EdgeInsets.all(44),
color: Colors.transparent,
child: Text(
widget.layerData.text.toString(),
style: TextStyle(
fontSize: widget.layerData.size,
),
), ),
), ),
), ),

View file

@ -51,7 +51,6 @@ class _EmojisState extends State<Emojis> {
context, context,
EmojiLayerData( EmojiLayerData(
text: emoji, text: emoji,
size: 32.0,
), ),
); );
}, },