skip to Main Content

Found out a strange problem when I was creating a rotation animation for an Icon.

I use RotationTransition to animate Icons.sync. And I also use Transform because I need a mirrored version of the icon. The results is strange – it is not rotating, but moving by circular trajectory and then breaking. Without Transform everything is OK.

How it works now (new clicks on the button doesn’t start animation, only page loading starts it):
enter image description here

How it works without Transform (as expexted)
enter image description here

The animated icon widget code:

class _AnimatedSyncIconState extends State<AnimatedSyncIcon>
    with SingleTickerProviderStateMixin {
  late final AnimationController controller;
  late final Animation<double> rotateAnimation;

  @override
  void initState() {
    super.initState();
    controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 1));
    rotateAnimation = CurvedAnimation(parent: controller, curve: Curves.linear);
    _animate();
  }

  @override
  void didUpdateWidget(final AnimatedSyncIcon oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isActive != oldWidget.isActive) _animate();
  }

  void _animate() {
    if (widget.isActive) {
      controller.repeat();
    } else {
      controller.reset();
    }
  }

  @override
  Widget build(final BuildContext context) {
    return RotationTransition(
      turns: rotateAnimation,
      child: Transform(
        transform: Matrix4.rotationY(pi),
        child: const Icon(Icons.sync),
      ),
    );
  }
}

How to make it work properly with the mirrored icon?

2

Answers


  1. Here is an example to animate icon, you may adjust below example code according to your need. i hope it will help you.

    import 'dart:math' as math;
    import 'package:flutter/material.dart';
    
    class AnimatedSyncIcon extends StatefulWidget {
      AnimatedSyncIcon();
    
      @override
      State<AnimatedSyncIcon> createState() => _AnimatedSyncIconState();
    }
    
    class _AnimatedSyncIconState extends State<AnimatedSyncIcon>
        with SingleTickerProviderStateMixin {
      late final AnimationController _controller =
          AnimationController(vsync: this, duration: Duration(seconds: 2))
            ..repeat(reverse: true);
    
      @override
      Widget build(final BuildContext context) {
        return Scaffold(
          body: Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (_, child) {
                return Transform.rotate(
                  angle: _controller.value * 2 * math.pi,
                  child: child,
                );
              },
              child: Icon(Icons.sync),
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. you need one simple change, just transform your icon like this:

      @override
      Widget build(final BuildContext context) {
        return RotationTransition(
          turns: rotateAnimation,
            child: Transform.scale(
            scaleX: -1,
            child: const Icon(
              Icons.sync, 
            ),
          ),
        );
      }
    

    now your icon will be mirrored and rotating correctly and you don’t even need to import dart:math anymore

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search