【问题标题】:Flutter - How to rotate shadow with object?Flutter - 如何用对象旋转阴影?
【发布时间】:2021-11-19 08:33:46
【问题描述】:

所以我有一个沿 Y 轴旋转的对象。我使用了一个带有盒子阴影的容器来投射物体的阴影。

不,我有一个可以旋转的容器,但它在中心处有点失去宽度(如果你知道变换是如何工作的)......我如何旋转容器而不使其在整个旋转过程中失去宽度。

class _TestState extends State<Test> with TickerProviderStateMixin {
 late final AnimationController _controller;
 @override
 void initState() {
  _controller = AnimationController(
    vsync: this,
    duration: Duration(seconds: 25),
  )..repeat();
  super.initState();
}

Widget build(BuildContext context) {
 double screenHeight = MediaQuery.of(context).size.height;
 double screenWidth = MediaQuery.of(context).size.width;

return Scaffold(
  backgroundColor: Colors.black,
  appBar: AppBar(
    title: Text('3D Demo'),
    backgroundColor: Colors.black,
  ),
  body: Center(
    child: Container(
      padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
      // width: double.infinity,
      // height: double.infinity,

      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          // stops: [0.1, 0.5, 0.7, 0.9],
          colors: [Colors.black, Colors.black],
        ),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Divider(),
          Divider(),


          SizedBox(
            height: screenHeight * 0.5,
            child: Stack(
              children: [


                Center(
                  child: AnimatedBuilder(
                    animation: _controller,
                    builder: (_, child) {
                      return Transform(
                        alignment: Alignment.center,
                        transform: Matrix4.identity()
                          ..setEntry(3, 2, 0.001)
                          //..rotateX(0.01 * _offset.dy)
                          //   ..rotateY(0.01 * _offset.dx),
                          // alignment: FractionalOffset.center,
                          ..rotateY(
                            _controller.value * (-math.pi),
                          ),
                        // ..rotateZ(
                        //   math.pi *
                        //       2 *
                        //       _controller
                        //           .value, //change 0 to any value to rotate z Axis
                        // ),
                        child: child,
                      );
                    },
                    child: Container(
                      child: AnimatedContainer(
                        //transform: Matrix4.skewX(10),
                        height: 100,
                        width: double.infinity,
                        duration: const Duration(milliseconds: 5000),
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(100),

                            boxShadow:

                                [
                              BoxShadow(
                                color: Colors.yellow.withOpacity(0.6),
                                spreadRadius: 1,
                                blurRadius: 16,
                                offset: const Offset(-0, 0),
                              ),

                            ]
                            
                            ),
                      ),
                    ),
                  ),
                ),

              ],
            ),
          ),
        ],
      ),
    ),
   ),
  );
 }
}

【问题讨论】:

  • 你的意思是你想让阴影看起来像它有一个 Z 维度?
  • 是的...它必须平地,所以它应该有一个Z方向,然后它应该沿着Y轴旋转。
  • 您想要多大的 Z 轴?因为阴影显然没有 Z 轴 IRL。如果您只是想掩盖短暂的隐身时刻,则可以使用涉及覆盖的 hacky 解决方案。 “失去宽度”到底是什么意思?
  • 大约40-50(与当前高度大致相同)。目前它看起来像一个垂直容器,我希望它看起来像一个水平容器;因此当前高度将变为其在 Z 轴上的长度,并且高度(Y 轴)会更小。正如您在 gif 中看到的那样,失去其宽度意味着当容器与屏幕完全垂直时,它会消失片刻。影子不会就这样消失。想象一辆沿 Y 轴旋转的载具,它的影子将如何随之旋转;这就是我想要实现的目标。

标签: flutter animation rotation containers


【解决方案1】:

我想这就是你想要的。将以下代码粘贴到DartPad 中,您可以看到这只是添加更多旋转的问题。希望有人可以向我展示一种更有效的转换方式,但这是可行的。

import 'package:flutter/material.dart';
import 'dart:math' as math;

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Test(),
        ),
      ),
    );
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  bool isAnimating = false;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 10),
    );
    super.initState();
  }

  @override
  dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        title: Text('3D Demo'),
        backgroundColor: Colors.black,
      ),
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (_, child) {
            return Transform(
              alignment: FractionalOffset.center,
              transform: Matrix4.identity()
                ..setEntry(3, 2, 0.002)
                ..rotateY(0.5 * -math.pi)
                ..rotateZ(-0.1 * math.pi)
                ..rotateY((_controller.value - 0.5) * -math.pi)
                ..rotateX(0.5 * math.pi),
              child: child,
            );
          },
          child: Container(
            height: 100,
            width: 200,
            color: Colors.white,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          isAnimating ? _controller.stop() : _controller.repeat();
          setState(() {
            isAnimating = !isAnimating;
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

【讨论】:

  • 天才!你能告诉我是否可以让轮换从特定位置开始吗?如,矩形(长度)在渲染时应该垂直于屏幕;然后它应该从那个位置开始旋转......
  • @whoadityanawandar 我用您描述的功能更新了我的答案。稍微更改了控制器值(您可以交换容器尺寸)并添加停止/启动按钮
  • @PatrikMahomes 谢谢伙计,我已经发布了另一个问题,你能看看吗? stackoverflow.com/questions/69356571/…
猜你喜欢
  • 2021-02-09
  • 2011-08-12
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2011-10-24
相关资源
最近更新 更多