在 Flutter 中显示一半的旋转图像

Show half of rotating image in Flutter

我正在创建一个圆形旋转的动画(左图)。

我的目标是只有一半的动画可见(右图中的蓝色矩形)。在 Web 开发中,我会创建一个带有隐藏溢出的 div。我无法让它在 Flutter 中工作。我调查了 ClipRect,但运气不佳。

这是我用来旋转图像的 Flutter 代码:

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

  @override
  _ImageRotateState createState() => _ImageRotateState();
}

class _ImageRotateState extends State<ImageRotate>
    with SingleTickerProviderStateMixin {
  late AnimationController animationController;

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 30),
    );

    animationController.repeat();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      // color: Colors.white,
      child: AnimatedBuilder(
        animation: animationController,
        child: SizedBox(
          child: Image.asset('assets/svg/circle.png'),
        ),
        builder: (BuildContext context, Widget? _widget) {
          return Transform.rotate(
            angle: animationController.value * 6.3,
            child: _widget,
          );
        },
      ),
    );
  }
}

您可以尝试使用 Stack,它使用 clipBehavior: Clip.hardEdge 选项剪辑其内容,然后移动它它高度的一半。您将 Stack 包装在 SizedBox 中以将其高度限制为圆高度的一半,并将高度也应用于 ImageRotate,如此:


Center(
  child: SizedBox(
    height: 200,
    width: 400,
    child: Stack(
       clipBehavior: Clip.hardEdge,
       children: [
         Positioned(
            top: 0,
            child: ImageRotate()
         )
       ]
    )
 ),
)

到你的 ImageRotate:

SizedBox(
   child: Image.asset('assets/svg/circle.png', width: 400, height: 400, fit: BoxFit.contain)
),

检查此 Gist 并 运行 通过 DartPad.dev 检查它。您的输出应如下所示:

这是一个想法,

  1. 按此顺序将您的圆圈和矩形不透明框(可能是容器)放入 Stack Widget。

  2. 为容器提供矩形框一半的大小和颜色,以隐藏圆圈。

  3. 将容器包裹在 Positioned Widget 中,并将其与蓝色矩形的下半部分对齐。

    @override
    Widget build(BuildContext context) {
     return Scaffold(
       body: SafeArea(
         child: Container(
           height: 400,
           width: 400,
           alignment: Alignment.center,
           child: Stack(children: [
             AnimatedBuilder(
               animation: animationController,
               child: ClipOval(
                 child: Image.asset(
                   'assets/images/download.png',
                   width: 400,
                   height: 400,
                   fit: BoxFit.cover,
                 ),
               ),
               builder: (BuildContext context, Widget? _widget) {
                 return Transform.rotate(
                   angle: animationController.value * 6.3,
                   child: _widget,
                 );
               },
             ),
             Positioned(
               bottom: 0,
               right: 0,
               child: Container(
                 width: 400,
                 height: 200,
                 color: Colors.white,
               ),
             )
           ]),
         ),
       ),
     );
    }
    

在此代码中:

  1. 我将 ClipOval 用于圆形图像,因为我的图像是方形的。
  2. 父容器有高度和宽度,还有子定位容器(父高度的一半)。
  3. 以及用于避免设备边距的 SafeArea。

这是您要找的吗?