import 'package:flutter/material.dart'; class TrackpadWidget extends StatefulWidget { final Function(String type, Map values) onUpdate; TrackpadWidget({required this.onUpdate}); @override _TrackpadWidgetState createState() => _TrackpadWidgetState(); } class _TrackpadWidgetState extends State { double _scale = 1.0; Offset _offset = Offset.zero; double _rotation = 0.0; double _previousRotation = 0.0; void _handleUpdate(String type, Map values) { widget.onUpdate(type, values); } @override Widget build(BuildContext context) { return GestureDetector( onScaleStart: (details) { _previousRotation = _rotation; }, onScaleUpdate: (details) { setState(() { if (details.pointerCount == 1) { // Tek parmakla döndürme _rotation = (_previousRotation + details.rotation).clamp(0.0, 1.0); _handleUpdate('rotate', {'rotation': _rotation}); } else if (details.pointerCount == 2) { // İki parmakla kaydırma ve yakınlaştırma _scale = details.scale.clamp(0.0, 1.0); _offset = Offset( (details.focalPoint.dx / MediaQuery.of(context).size.width) .clamp(0.0, 1.0), (details.focalPoint.dy / MediaQuery.of(context).size.height) .clamp(0.0, 1.0), ); _handleUpdate('pan_zoom', {'scale': _scale, 'dx': _offset.dx, 'dy': _offset.dy}); } }); }, onScaleEnd: (details) { setState(() { _scale = 1.0; _offset = Offset.zero; _rotation = 0.0; _previousRotation = 0.0; }); _handleUpdate('end', { 'scale': _scale, 'dx': _offset.dx, 'dy': _offset.dy, 'rotation': _rotation }); }, child: Transform( transform: Matrix4.identity() ..translate(_offset.dx * MediaQuery.of(context).size.width, _offset.dy * MediaQuery.of(context).size.height) ..scale(_scale) ..rotateZ(_rotation * 2 * 3.141592653589793), alignment: FractionalOffset.center, child: Container( width: 200, height: 200, color: Colors.blue, child: Center(child: Text('Trackpad Area')), ), ), ); } }