Reputation: 13304
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
But the current behavior is that the heart starts out big and then slows down.
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
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
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