Show half of rotating image in Flutter

Issue

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 ClipRect without luck.

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

Solution

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 Gist and run it through DartPad.dev to check it out. Your output should look like this:

enter image description here

Answered By – Roman Jaquez

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *