Home > Enterprise >  Show half of rotating image in Flutter
Show half of rotating image in Flutter

Time:03-08

I am creating an animation where a circle is rotating (left image).

My goals is only having half of the animation visible (blue rectangle in right image). In web development I would have created a div with a hidden overflow. I can't get this to work in Flutter. I've looked into enter image description here

This is the Flutter code I am using to rotate the image:

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,
          );
        },
      ),
    );
  }
}

CodePudding user response:

You could try using a Stack that clips its contents using its clipBehavior: Clip.hardEdge option, then you shift it half way its height. You wrap the Stack in a SizedBox to constrain its height to half the height of the circle, and apply a height to the ImageRotate also, as such:


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

To your ImageRotate:

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

Check out this enter image description here

CodePudding user response:

Here's an idea,

  1. Put your circle and a rectangular opaque box(possibly container) in a Stack Widget in this order.

  2. Give the container half of your rectangular box's size and color that can hide the circle.

  3. Wrap the container in Positioned Widget and place it aligning to the bottom half of the blue rectangle.

    @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,
               ),
             )
           ]),
         ),
       ),
     );
    }
    

In this code:

  1. I used ClipOval for circular image cause my image was square.
  2. Parent container has height and width, as well as child positioned container(half of the parent height).
  3. And SafeArea for avoiding device margins.

Is this what you're looking for?

  • Related