Флаттер, Почему элемент перемещения InteractiveViewer TransfromController Matrix4 x, t изменен элементом масштаба?

#flutter #matrix

Вопрос:

код:

 void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
TickerProviderStateMixin.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with TickerProviderStateMixin {
  final TransformationController _transformationController =
  TransformationController();
  Animation<Matrix4>? _animationReset;
  late final AnimationController _controllerReset;
  late GlobalKey _key = GlobalKey();
  double? selectedPositionX;
  double? selectedPositionY;
  List<Offset> polygonPoints = [];

  void _onAnimateReset() {
    _transformationController.value = _animationReset!.value;
    if (!_controllerReset.isAnimating) {
      _animationReset!.removeListener(_onAnimateReset);
      _animationReset = null;
      _controllerReset.reset();
    }
  }

  void _animateResetInitialize() {
    _controllerReset.reset();
    print(_transformationController.value.toString());
    _animationReset = Matrix4Tween(
      begin: _transformationController.value,
      end: _transformationController.value,
    ).animate(_controllerReset);

    _animationReset!.addListener(_onAnimateReset);
    _controllerReset.forward();
  }

// Stop a running reset to home transform animation.
  void _animateResetStop() {
    _controllerReset.stop();
    _animationReset?.removeListener(_onAnimateReset);
    _animationReset = null;
    _controllerReset.reset();
  }

  void _onInteractionStart(ScaleStartDetails details) {
    if (_controllerReset.status == AnimationStatus.forward) {
      _animateResetStop();
    }
  }

  @override
  void initState() {
    super.initState();
    _controllerReset = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    print(_transformationController.value.toString());

  }

  @override
  void dispose() {
    _controllerReset.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.primary,
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: const Text('Controller demo'),
      ),
      body: Center(
        child: Container(
          color: Colors.yellow,
          height: MediaQuery.of(context).size.width,
          width: MediaQuery.of(context).size.width,
          child: InteractiveViewer(
            boundaryMargin: const EdgeInsets.all(double.infinity),
            transformationController: _transformationController,
            minScale: 0.1,
            maxScale: 2.0,
            onInteractionStart: _onInteractionStart,
            onInteractionUpdate: (details) {},
            onInteractionEnd: (details) {
              _animateResetInitialize();
            },
            child: OverflowBox(
              maxWidth: double.infinity,
              maxHeight: double.infinity,
              child: Container(
                key: _key,
                width: MediaQuery.of(context).size.width *2,
                height: MediaQuery.of(context).size.height *2,
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.topRight,
                    colors: <Color>[
                      Colors.purpleAccent,
                      Colors.red,
                      Colors.white,
                      Colors.greenAccent,
                      Colors.amber,
                      Colors.black
                    ],
                    stops: <double>[0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
      persistentFooterButtons: <Widget>[
        IconButton(
          onPressed: _animateResetInitialize,
          tooltip: 'Reset',
          color: Theme.of(context).colorScheme.surface,
          icon: const Icon(Icons.replay),
        ),
      ],
    );
  }

}
 

Сначала он печатает эти матрицы 4

 I/flutter ( 9651): [0] 1.0,0.0,0.0,0.0
I/flutter ( 9651): [1] 0.0,1.0,0.0,0.0
I/flutter ( 9651): [2] 0.0,0.0,1.0,0.0
I/flutter ( 9651): [3] 0.0,0.0,0.0,1.0
 

и скриншот такой:

введите описание изображения здесь

After this, I zoomed in those to this:

enter image description here

And second screenshot’s matrix4 is it:

 I/flutter ( 9651): [0] 0.30592490707054154,0.0,0.0,141.13913892048404
I/flutter ( 9651): [1] 0.0,0.30592490707054154,0.0,143.600351953026
I/flutter ( 9651): [2] 0.0,0.0,0.30592490707054154,0.0
I/flutter ( 9651): [3] 0.0,0.0,0.0,1.0
 

QUESTION:

Я узнал это 141.13913892048404 и 143.600351953026 о движении x, y и 0.30592490707054154 о том, насколько оно масштабировано. Я подумал , что 141.13913892048404 так и 143.600351953026 должно быть 0 , 0 потому что центр контейнера не изменился.

Но я был неправ, и я не знаю, почему центр контейнера изменился по масштабу.

  1. Почему это изменилось?
  2. Как рассчитать движение x, y по шкале?