I have a problem with the animation, I want the heart to start small, increase and then decrease in size, as shown in the gif below.

Desired animation

enter image description here

But the current behavior is that the heart starts out big and then slows down.

enter image description here

Would anyone know what it would take to fix the animation?

Here is the flutter code:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage();

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

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  Animation<double> _heartAnimation;
  AnimationController _heartController;

  @override
  void dispose() {
    _heartController.dispose();
    super.dispose();
  }

  void _animate() {
    _heartController
      ..reset()
      ..forward(from: 0.0)
      ..reverse(from: 1.0);
  }

  @override
  void initState() {
    super.initState();
    final quick = const Duration(milliseconds: 500);
    final scaleTween = Tween(begin: 0.0, end: 1.0);
    _heartController = AnimationController(duration: quick, vsync: this);
    _heartAnimation = scaleTween.animate(
      CurvedAnimation(
        parent: _heartController,
        curve: Curves.elasticOut,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ScaleTransition(
          scale: _heartAnimation,
          child: Icon(Icons.favorite, size: 160.0, color: Colors.red),
        )
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _animate();
        },
        child: Icon(Icons.favorite_rounded),
      ),
    );
  }
}


Solution 1: Andrej

Try this code, it works for me perfectly. If you have any questions please let know.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: MyHomePage());
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage();

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

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  Animation<double> animation;
  AnimationController controller;

  @override
  void initState() {
    super.initState();
    final quick = const Duration(milliseconds: 500);
    final scaleTween = Tween(begin: 0.0, end: 1.0);
    controller = AnimationController(duration: quick, vsync: this);
    animation = scaleTween.animate(
      CurvedAnimation(
        parent: controller,
        curve: Curves.fastLinearToSlowEaseIn,
      ),
    )..addListener(() {
      setState(() => scale = animation.value);
    });

  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  void _animate() {
    animation
    ..addStatusListener((AnimationStatus status) {
      if (scale == 1.0) {
        controller.reverse();
      } 
    });
    controller.forward();
  }

  double scale = 0.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Transform.scale(
          scale: scale,
          child: Icon(
            Icons.favorite,
            size: 160.0,
            color: Colors.red
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _animate();
        },
        child: Icon(Icons.favorite_rounded),
      )
    );
  }
}