Home > OS >  Flutter how to animate matrix4 translate when button is tapped
Flutter how to animate matrix4 translate when button is tapped

Time:09-28

I have 2 button, to control a scrolling of InteractiveViewer widget, left and right, hopefully I can add up and down later own my own after i have better understanding of matrix4Tween

right now the button is as such

       Row(
          children: [
            ElevatedButton(
              onPressed: () {
                controller.value = Matrix4.identity()..translate(0.0, 0.0);
              },
              child: Text('<'),
            ),
            ElevatedButton(
              onPressed: () {
                controller.value = Matrix4.identity()..translate(-(width), 0.0);
              },
              child: Text('>'),
            ),
          ],
        ),

and below it is a interactiveViewer widget that contains 4 gridview

     Container(
          color: Colors.grey,
          width: gridboxwidth,
          height: gridboxheight,
          child: InteractiveViewer(
            alignPanAxis: true,
            constrained: false,
            transformationController: controller,
            scaleEnabled: true,
            minScale: 0.1,
            maxScale: 1,
            child: Column(
              children: [
                Row(
                  children: [
                    grid1(size),
                    grid3(size),
                  ],
                ),
                Row(
                  children: [
                    grid2(size),
                    grid4(size),
                  ],
                ),
              ],
            ),
          ),
        ),

and it works just fine, on tap of the button, the grid moves into view, but I don't think it is intuitive enough and some animation might need to be added to show that the grid has changed.

Any help and guidance is greatly appreciated.

CodePudding user response:

this is a sample widget that uses Matrix4Tween, the important lines of code are marked with // NOTE: comments:

class FooInteractiveViewer extends StatefulWidget {
  @override
  _FooInteractiveViewerState createState() => _FooInteractiveViewerState();
}

class _FooInteractiveViewerState extends State<FooInteractiveViewer> with TickerProviderStateMixin {
  AnimationController _ctrl;
  Animation<Matrix4> _matrixAnimation = AlwaysStoppedAnimation(Matrix4.identity());
  final _transformationController = TransformationController();

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 500),
    )
      // NOTE: add listener to be called each time _ctrl changes
      ..addListener(_listener);
  }

  void _listener() {
    print(MatrixUtils.transformPoint(_matrixAnimation.value, Offset.zero));
    // NOTE: this is the most important part of this code:
    _transformationController.value = _matrixAnimation.value;
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        return InteractiveViewer(
          // panEnabled: false,
          alignPanAxis: true,
          constrained: false,
          transformationController: _transformationController,
          child: SizedBox(
            width: constraints.maxWidth * 2,
            height: constraints.maxHeight * 2,
            child: Column(
              children: [
                Expanded(
                  child: Row(
                    children: [
                      button(Colors.red, constraints.biggest, 1, 0, 'green'),
                      button(Colors.green, constraints.biggest, 0, 1, 'blue'),
                    ],
                  ),
                ),
                Expanded(
                  child: Row(
                    children: [
                      button(Colors.blue, constraints.biggest, 1, 1, 'orange'),
                      button(Colors.orange, constraints.biggest, 0, 0, 'red'),
                    ],
                  ),
                ),
              ],
            ),
          )
        );
      },
    );
  }

  Widget button(Color color, Size size, int x, int y, String name) {
    return Expanded(
      child: Material(
        color: color,
        child: InkWell(
          onTap: () async {
            // timeDilation = 10;
            // NOTE: create new Animation<Matrix4> that will be used inside _listener
            _matrixAnimation = Matrix4Tween(
              begin: _transformationController.value,
              end: Matrix4.translationValues(-size.width * x, -size.height * y, 0)
            ).chain(CurveTween(curve: Curves.decelerate)).animate(_ctrl);
            // NOTE: lets start the show
            await _ctrl.forward(from: 0);
            print('### animation finished ###');
          },
          child: Center(child: Text('go to $name', textScaleFactor: 2)),
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _ctrl.dispose();
  }
}
  • Related