Flutter 实现酷炫的3D效果示例代码

    此文讲解3个酷炫的3D动画效果。

    下面是要实现的效果:

    Flutter 中3D效果是通过 Transform 组件实现的,没有变换效果的实现:

    
    class TransformDemo extends StatelessWidget {
     @override
     Widget build(BuildContext context) {
     return Scaffold(
     appBar: AppBar(
     title: Text('3D 变换Demo'),
     ),
     body: Container(
     alignment: Alignment.center,
     color: Colors.white,
     child: Text('3D 变换Demo'),
     ),
     );
     }
    }

    通过 GestureDetector 组件添加滑动事件监听:

    
    @override
    Widget build(BuildContext context) {
     return Scaffold(
     appBar: AppBar(
     title: Text('3D 变换Demo'),
     ),
     body: GestureDetector(
     onPanUpdate: (details) {
     print('$details');
     },
     child: Container(
     alignment: Alignment.center,
     color: Colors.white,
     child: Text('3D 变换Demo'),
     ),
     ),
     );
    }

    添加 Transform 对组件进入旋转:

    
    @override
    Widget build(BuildContext context) {
     return Transform(
     transform: Matrix4.identity()
     ..setEntry(3, 2, 0.001)
     ..rotateX(pi/6)
     ..rotateY(pi/6),
     alignment: Alignment.center,
     child: Scaffold(
     appBar: AppBar(
      title: Text('3D 变换Demo'),
     ),
     body: GestureDetector(
      onPanUpdate: (details) {
      },
      child: Container(
      alignment: Alignment.center,
      color: Colors.white,
      child: Text('3D 变换Demo'),
      ),
     ),
     ));
    }

    将滑动的偏移和旋转进行关联:

    
    class TransformDemo extends StatefulWidget {
     @override
     _TransformDemoState createState() => _TransformDemoState();
    }
    
    class _TransformDemoState extends State<TransformDemo> {
     double _rotateX = .0;
     double _rotateY = .0;
    
     @override
     Widget build(BuildContext context) {
     return Transform(
     transform: Matrix4.identity()
      ..rotateX(_rotateX)
      ..rotateY(_rotateY),
     alignment: Alignment.center,
     child: Scaffold(
      appBar: AppBar(
      title: Text('3D 变换Demo'),
      ),
      body: GestureDetector(
      onPanUpdate: (details) {
      setState(() {
      _rotateX += details.delta.dy * .01;
      _rotateY += details.delta.dx * -.01;
      });
      },
      child: Container(
      alignment: Alignment.center,
      color: Colors.white,
      child: Text('3D 变换Demo'),
      ),
      ),
     ));
     }
    }

    基本已经实现了3D效果,但效果比较生硬,尤其垂直方向旋转的时候远点和近点在屏幕上的宽度是一样,

    添加近大远小的效果:

    
    Transform(
     transform: Matrix4.identity()
     ..setEntry(3, 2, 0.001)
     ..rotateX(_rotateX)
     ..rotateY(_rotateY),
     ...

    翻书效果

    上面的效果类似于翻书的效果。

    实现的原理:

    将图片左右切割为两部分,两张图片共分割为4个新的组件,如下图,分别为1、2、3、4

    代码实现:

    
    _child1 = ClipRect(
     child: Align(
     alignment: Alignment.centerLeft,
     widthFactor: 0.5,
     child: child1,
     ),
    );
    _child2 = ClipRect(
     child: Align(
     alignment: Alignment.centerRight,
     widthFactor: 0.5,
     child: child1,
     ),
    );
    
    _child3 = ClipRect(
     child: Align(
     alignment: Alignment.centerLeft,
     widthFactor: 0.5,
     child: child2,
     ),
    );
    
    _child4 = ClipRect(
     child: Align(
     alignment: Alignment.centerRight,
     widthFactor: 0.5,
     child: child2,
     ),
    );

    将第一张图片放在第二种图片的上面,先旋转 组件2 从 0度到 90度,然后再旋转 组件3 从 -90度到0度,代码实现:

    
    Row(
     mainAxisAlignment: MainAxisAlignment.center,
     children: <Widget>[
     Stack(
     children: [
     _child1,
     Transform(
      alignment: Alignment.centerRight,
      transform: Matrix4.identity()
      ..setEntry(3, 2, 0.001)
      ..rotateY(_animation1.value),
      child: _child3,
     ),
     ],
     ),
     Container(
     width: 3,
     color: Colors.white,
     ),
     Stack(
     children: [
     _child4,
     Transform(
      alignment: Alignment.centerLeft,
      transform: Matrix4.identity()
      ..setEntry(3, 2, 0.001)
      ..rotateY(_animation.value),
      child: _child2,
     )
     ],
     )
     ],
    )

    动画控制器设置:

    
    @override
    void initState() {
     init();
     _controller =
     AnimationController(vsync: this, duration: Duration(seconds: 5))
     ..addListener(() {
      setState(() {});
     });
     _animation = Tween(begin: .0, end: pi / 2)
     .animate(CurvedAnimation(parent: _controller, curve: Interval(.0, .5)));
     _animation1 = Tween(begin: -pi / 2, end: 0.0).animate(
     CurvedAnimation(parent: _controller, curve: Interval(.5, 1.0)));
     _controller.forward();
     super.initState();
    }

    其中 child1, child2为两种图片,代码如下:

    
    _FlipUpDemoState(
     Container(
     width: 300,
     height: 400,
     child: Image.asset(
     'assets/images/b.jpg',
     fit: BoxFit.cover,
     ),
     ),
     Container(
     width: 300,
     height: 400,
     child: Image.asset(
     'assets/images/c.jpeg',
     fit: BoxFit.cover,
     ),
     ))

    最后生成的效果就是开始的翻书效果。

    上面是左右翻页效果,同理换成上下翻页效果:

    
    @override
    Widget build(BuildContext context) {
     return Scaffold(
     appBar: AppBar(),
     body: Column(
     mainAxisAlignment: MainAxisAlignment.center,
     children: <Widget>[
     Stack(
      children: [
      _upperChild1,
      Transform(
      alignment: Alignment.bottomCenter,
      transform: Matrix4.identity()
      ..setEntry(3, 2, 0.003)
      ..rotateX(_animation1.value),
      child: _upperChild2,
      ),
      ],
     ),
     SizedBox(
      height: 2,
     ),
     Stack(
      children: [
      _lowerChild2,
      Transform(
      alignment: Alignment.topCenter,
      transform: Matrix4.identity()
      ..setEntry(3, 2, 0.003)
      ..rotateX(_animation.value),
      child: _lowerChild1,
      )
      ],
     )
     ],
     ),
     );
    }

    到此这篇关于Flutter 实现酷炫的3D效果示例代码的文章就介绍到这了,更多相关Flutter 实现酷炫的3D效果内容请搜索lingkb以前的文章或继续浏览下面的相关文章希望大家以后多多支持lingkb!