rafaelcb21
rafaelcb21

Reputation: 13304

Animation, increase and decrease the size

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

Upvotes: 4

Views: 3875

Answers (2)

Bhushan Gayakwad
Bhushan Gayakwad

Reputation: 1

You can achieve the desired animation using the zoom-in effect, we can learn it through the Flutter doc, or refer to the code below:

class _ManageScale extends State<YourClass> with TickerProviderStateMixin{

late final AnimationController controller = AnimationController(
 duration: const Duration(seconds:2),    
vsync: this,
)..repeat(reverse:true) ;
late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve:Curve.fastOutSlowIn,  
);

 Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ScaleTransition(
          scale: _animation,
          child: const Padding(
            padding: EdgeInsets.all(8.0),
            child: <Place_Your_Heart_Shape>(size: 150.0),
          ),
        ),
      ),
    );
  }
`


class _ManageScale extends State<YourClass> with TickerProviderStateMixin{

late final AnimationController controller = AnimationController(
 duration: const Duration(seconds:2),    
vsync: this,
)..repeat(reverse:true) ;//putting repeat reverse true is make your container big and small in same order

late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve:Curve.fastOutSlowIn,  
);

//for proper implementation of above stateful widget see doc

now use above animation as a property in your widget which is _animation

 Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ScaleTransition(
          scale: _animation,
          child: const Padding(
            padding: EdgeInsets.all(8.0),
            child: <Place_Your_Heart_Shape>(size: 150.0),
          ),
        ),
      ),
    );
  }

Upvotes: 0

Andrej
Andrej

Reputation: 3225

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

Upvotes: 6

Related Questions