0

So far I've been able to drag the widget around the screen but the scale doesn't change. I've printed the scale and it is always shown to be one.

Here's the code I've written

            Positioned(
              top: (_y1 - _radius1).toDouble(),
              left: (_x1 - _radius1).toDouble(),
              child: GestureDetector(
                onScaleStart: (details) {
                  _baseScaleFactor = _scaleFactor;
                },
                onScaleUpdate: (ScaleUpdateDetails details) {
                  setState(() {
                    _scaleFactor = _baseScaleFactor * details.scale;
                    _radius1 = _scaleFactor * _radius1;
                    _x1 = min(392,
                        max(0, _x1 + details.focalPointDelta.dx.toInt()));
                    _y1 = min(512,
                        max(0, _y1 + details.focalPointDelta.dy.toInt()));
                    debugPrint("x1: $_x1\ty1: $_y1");
                    debugPrint("R1:$_radius1 \tScale: ${details.scale}");
                    debugPrint("focal: ${details.focalPoint}");
                    debugPrint("focal delta: ${details.focalPointDelta}");
                    debugPrint(
                        "horizontal Scale: ${details.horizontalScale}");
                    debugPrint("Vertical Scale: ${details.verticalScale}");
                  });
                },

                child: Container(
                  height: _radius1.toDouble() * 2,
                  width: _radius1.toDouble() * 2,
                  decoration: BoxDecoration(
                    color: const Color.fromARGB(148, 180, 60, 52),
                    borderRadius:
                        BorderRadius.circular(_radius1.toDouble()),
                  ),
                  child: CustomPaint(
                    painter: CirclePainter(_radius1.toInt(),
                        _radius1.toInt(), _radius1.toInt()),
                  ),
                ),
                // child: CustomPaint(
                //   painter: CirclePainter(0, 0, _radius1),
                // ),
              ),
            ),

1 Answers1

0

on scale update is called with one or two fingers touching the screen. you should check how many pointers in details. something like this:

class ZoomAndDragExample extends StatefulWidget {


const ZoomAndDragExample({super.key, required this.child});

  final Widget child;

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

    class _ZoomAndDragExampleState extends State<ZoomAndDragExample> {
  double _scale = 1.0;
  double _previousScale = 1.0;
  Offset _offset = Offset.zero;
  Offset _previousOffset = Offset.zero;
  Offset _currentFocalPoint = Offset.zero;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onScaleStart: (details) {
        if (details.pointerCount == 2){
          _previousScale = _scale;
          _currentFocalPoint = details.focalPoint;
        } else if(details.pointerCount == 1){
          _previousOffset = details.focalPoint;
        }
      },
      onScaleUpdate: (details) {
        setState(() {
          if (details.pointerCount == 2) {
            _scale = _previousScale * details.scale;
            _scale = _scale.clamp(1, 10);
          }

          if (details.pointerCount == 1) {
            final Offset delta = details.focalPoint - _previousOffset;
            _previousOffset = details.focalPoint;
            _offset += delta;
        }
        });
      },
      onScaleEnd: (details) {
        _previousScale = 1.0;
      },
      child: Transform(
          alignment: Alignment.center,
          transform: Matrix4.identity()
            ..translate(_offset.dx, _offset.dy)
            ..scale(_scale),
          child: Container(color:colors.red,width:100,height:100,
        ),
    );
  }
}