【问题标题】:Flutter: Matrix4 Off-center rotation during animated transitionFlutter:动画过渡期间的 Matrix4 偏离中心旋转
【发布时间】:2022-11-11 04:42:48
【问题描述】:

描述:

您好,我正在尝试为对象的旋转设置动画。 为此,我使用 Matrix4 来控制对象的旋转点。 在动画过渡期间我有一个奇怪的行为。


问题 :

为什么我的绿色方块在动画期间不能保持围绕其中心的旋转?


编码 :

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

  @override
  State<NodeV3View> createState() => _NodeV3ViewState();
}

class _NodeV3ViewState extends State<NodeV3View> {
  
  bool isExpand = false;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var controller = Provider.of<CompteurProvider2>(context);

    return Scaffold(
        body: LayoutBuilder(
          builder: (context, constraints){
            return Consumer<CompteurProvider2>(builder :(ctx , provider , child){
              return GestureDetector(
                onTap: () => setState(() {}),
                child: Container(
                  color: Colors.yellow,
                  width: 300,
                  height: 300,
                  child: Stack(
                    children: [
                      Positioned(
                        left: 150 - 50,// => Yellow Square / 2 - Green Square / 2
                        top : 150 - 50,
                        child: InkWell(
                          onTap: (){
                            setState(() {
                              isExpand = !isExpand;
                            });
                          },
                          child: AnimatedContainer(
                            duration: const Duration(milliseconds: 500),
                            width: 100,
                            height: 100,
                            decoration: BoxDecoration(
                              color: Colors.green,
                            ),
                          transform: Matrix4Transform()
                              .rotateDegrees(
                                  isExpand == true
                                      ? 180
                                      : 0,
                                  origin: Offset(50, 50)
                              )
                              .matrix4,
                          ),
                        ),
                      )
                    ],
                  ),
                )
              );
            });
          },
        )
    );
  }
}

任何有关实现此目的的最佳方法的指导将不胜感激。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    transformAlignment: FractionalOffset.center 添加到 AnimatedContainer。

    【讨论】:

    • 谢谢,我还删除了 Matrix4Transform() 中的原点
    【解决方案2】:

    我希望这个可以帮助你

    此代码仅旋转一次框,但您将为您想要的东西添加条件

    import 'dart:math';
    import 'package:flutter/material.dart';
    
    class TransformExample extends StatefulWidget {
      const TransformExample({Key? key}) : super(key: key);
    
      @override
      State<TransformExample> createState() => _TransformExampleState();
    }
    
    class _TransformExampleState extends State<TransformExample>
        with TickerProviderStateMixin {
      late AnimationController animationController =
          AnimationController(vsync: this, duration: const Duration(seconds: 2));
    
      @override
      void dispose() {
        super.dispose();
        animationController.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: InkWell(
              onTap: () => setState(() {
                animationController.forward();
              }),
              child: AnimatedBuilder(
                  animation: animationController,
                  child: Container(
                    height: 150.0,
                    width: 150.0,
                    color: Colors.blueGrey,
                  ),
                  builder: (BuildContext context, Widget? child) {
                    return Transform.rotate(
                      angle: animationController.value * 2.0 * pi,
                      child: child,
                    );
                  }),
            ),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      如果您只想沿 z 轴旋转它,更简单的方法是使用 RotationTransition 小部件,请查看 this existing answer here

      如果您想沿不同的轴旋转,例如,通过沿 x 轴和 y 轴旋转制作 3D 立方体,您可以查看此video tutorial here

      【讨论】:

        【解决方案4】:
        import 'dart:math';
        import 'package:flutter/material.dart';
        
        void main() => runApp(const MyApp());
        
        class MyApp extends StatelessWidget {
          const MyApp({super.key});
        
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Flutter 3D Cube Effect',
              debugShowCheckedModeBanner: false,
              theme: ThemeData(
                primarySwatch: Colors.green,
              ),
              home: Scaffold(
                  body: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  const SizedBox(height: 50),
                  const Text('3D Cube', style: TextStyle(fontSize: 30)),
                  Expanded(
                    child: Pseudo3dSlider(),
                  ),
                ],
              )),
            );
          }
        }
        
        class Pseudo3dSlider extends StatefulWidget {
          @override
          _Pseudo3dSliderState createState() => _Pseudo3dSliderState();
        }
        
        class _Pseudo3dSliderState extends State<Pseudo3dSlider> {
          Map<String, Offset> offsets = {
            'start': Offset(70, 100),
            'finish': Offset(200, 100),
            'center': Offset(100, 200),
          };
        
          double originX = 0;
          double x = 0;
        
          void onDragStart(double originX) => setState(() {
                this.originX = originX;
              });
        
          void onDragUpdate(double x) => setState(() {
                this.x = originX - x;
              });
        
          double get turnRatio {
            const step = -150.0;
            var k = x / step;
            k = k > 1 ? 1 : (k < 0 ? 0 : k);
            return 1 - k;
          }
        
          @override
          Widget build(BuildContext context) {
            return GestureDetector(
              behavior: HitTestBehavior.opaque,
              onPanStart: (details) => onDragUpdate(details.globalPosition.dx),
              onPanUpdate: (details) => onDragUpdate(details.globalPosition.dx),
              child: Slider(
                k: turnRatio,
                children: [
                  const _Side(
                    color: Colors.blueAccent,
                    number: 1,
                  ),
                  _Side(
                    color: Colors.redAccent.shade200,
                    number: 2,
                  ),
                ],
              ),
            );
          }
        }
        
        class _Side extends StatelessWidget {
          const _Side({Key? key, required this.color, required this.number})
              : super(key: key);
        
          final Color color;
          final int number;
        
          @override
          Widget build(BuildContext context) {
            return Container(
              width: 150,
              height: 150,
              color: color,
              child: Center(
                child: Text(
                  number.toString(),
                  style: const TextStyle(fontSize: 14),
                ),
              ),
            );
          }
        }
        
        class Slider extends StatelessWidget {
          Slider({
            Key? key,
            required this.children,
            required this.k,
          }) : super(key: key) {
            assert(children.length == 2, 'wronge nubmer of children');
          }
        
          final List<Widget> children;
          final double k;
        
          @override
          Widget build(BuildContext context) {
            var k1 = k;
            var k2 = 1 - k;
            print(k1);
            print(k2);
            return Row(
              children: <Widget>[
                Transform(
                  transform: Matrix4.identity()
                    ..setEntry(3, 2, 0.003)
                    ..rotateY(pi / 2 * k1),
                  alignment: FractionalOffset.centerRight,
                  child: children[0],
                ),
                Transform(
                  transform: Matrix4.identity()
                    ..setEntry(3, 2, 0.003)
                    ..rotateY(pi / 2 * -k2),
                  alignment: FractionalOffset.centerLeft,
                  child: children[1],
                ),
              ],
            );
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-08-02
          • 1970-01-01
          • 2020-11-17
          • 2018-10-25
          • 1970-01-01
          • 2012-06-05
          • 2019-07-21
          • 1970-01-01
          相关资源
          最近更新 更多