Search code examples
flutterdartanimationgesturedetector

Flutter: change widget scale when widget dragged


I am trying to change the widget size (scale) when I drag the widget up. I am using the GestureDetector and onPanUpdate method and Now I want to by Matrix4.identity to change the size of the widget:

 return GestureDetector(
        
        onPanUpdate: (details) {
          _position += details.delta;
          setState(() {});
        },

        child: Stack(
          children: [
            SizedBox(
              child: LayoutBuilder(builder: (context, constraints) {
                final milliSeconds = _isDragging ? 0 : 400;
                final center = constraints.smallest.center(Offset.zero);
                final scaledMatrix = Matrix4.identity();
                  // ..translate(center.dx, center.dy)
                  // ..scale(1.0, 0.5)
                  // ..translate(-center.dx, -center.dy);
                return AnimatedContainer(
                    curve: Curves.easeInOut,
                    duration: Duration(milliseconds: milliSeconds),
                    transform: scaledMatrix
                      ..translate(_position.dx, _position.dy),
                    child: widget.widgets[0]);
              }),
            ),
          ],
        )); 

Now when the widget is dragged I change the position but how can I change the widget scale ?


Solution

  • You can use Matrix4.identity()..scale api to achieve this.

    import 'package:flutter/material.dart';
    
    void main() => runApp(MaterialApp(
          home: Scaffold(appBar: AppBar(), body: _Drag()),
        ));
    
    class _Drag extends StatefulWidget {
      @override
      _DragState createState() => _DragState();
    }
    
    class _DragState extends State<_Drag> with SingleTickerProviderStateMixin {
      bool shouldScaleDown = true; // change value when needed
    
      double _top = 300; // distance to top
      double _left = 150; // distance to left
      double scale = 1;
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: <Widget>[
            Positioned(
              top: _top,
              left: _left,
              child: GestureDetector(
                onPanDown: (DragDownDetails e) {
                  print("fingure down: ${e.globalPosition}");
                },
                onPanUpdate: (DragUpdateDetails e) {
                  setState(() {
                    _left += e.delta.dx;
                    _top += e.delta.dy;
                    if (e.delta.dy > 0) {
                      scale = scale - 0.01;
                    }
                    if (e.delta.dy < 0) {
                      scale = scale + 0.01;
                    }
                  });
                },
                onPanEnd: (DragEndDetails e) {
                  print("fingure away from screen");
                  print(e.velocity);
                },
                child: AnimatedContainer(
                  color: Colors.blueAccent,
                  width: 100,
                  height: 100,
                  duration: Duration(milliseconds: 300),
                  transform: Matrix4.identity()..scale(scale, scale),
                  child: Container(),
                ),
              ),
            )
          ],
        );
      }
    }
    

    demo gif