Les Animations avec CustomPainter et Canvas dans Flutter
Sommaire
- 1- Objectif
- 2- CustomPainter et Canvas dans Flutter
- 2.1- Introduction à CustomPainter et Canvas
- 2.2- Les bases de CustomPainter
- 2.3- Comprendre le Canvas et les Paint
- 2.4- Création d’animations avec CustomPainter
- 2.5- Exemples pratiques avancés
- 2.6- Optimisation des performances
- 2.7- Intégration dans des applications réelles
- 2.8- Conclusion
- 2.8.1- Cours Flutter
Les Animations avec CustomPainter et Canvas dans Flutter
-
Objectif
-
CustomPainter et Canvas dans Flutter
-
Introduction à CustomPainter et Canvas
- Dans Flutter, CustomPainter est une classe abstraite que vous étendez pour définir votre propre logique de dessin, tandis que Canvas est l’outil de dessin lui-même, la surface sur laquelle vous effectuez les opérations de dessin.
- Vous implémentez la méthode paint(Canvas canvas, Size size) dans votre classe CustomPainter pour accéder au Canvas et utiliser des méthodes comme drawLine, drawCircle et drawPath avec un objet Paint pour créer des formes et des graphiques personnalisés.
- Qu’est-ce que CustomPainter ?
- CustomPainter est une classe abstraite dans Flutter qui permet de dessiner du contenu personnalisé directement sur le canevas.
- C’est l’équivalent de Custom View sur Android ou de UIView.draw() sur iOS.
- Pourquoi utiliser CustomPainter ?
- Créer des UI personnalisées impossibles avec les widgets standard.
- Réaliser des animations complexes et fluides.
- Dessiner des formes géométriques personnalisées.
- Créer des visualisations de données complexes.
- Développer des jeux et expériences interactives.
- Cycle de vie de CustomPainter
-
Les bases de CustomPainter
- Structure de base
- Utilisation avec un widget
-
Comprendre le Canvas et les Paint
- L’objet Canvas permet de dessiner :
- Formes géométriques (cercles, rectangles, lignes).
- Chemins (paths) personnalisés.
- Images et bitmaps.
- Texte.
- L’objet Paint définit comment dessiner :
- Couleurs et dégradés.
- Styles de trait (remplissage ou contour).
- Épaisseur du trait.
- Effets (ombres, filtres).
- Exemples de configuration Paint
-
Création d’animations avec CustomPainter
- AnimationController et TickerProvider
-
Exemples pratiques avancés
- Animation de vagues liquides.
- Visualisation de données animée.
- Effet de particules animées.
- Horloge analogique animée.
-
Optimisation des performances
- Bien utiliser
shouldRepaint
. - Éviter les allocations dans
paint()
. - Utiliser des layers pour les parties statiques.
- Simplifier les calculs complexes via du pré-calcul.
-
Intégration dans des applications réelles
- Combinaison avec des widgets Flutter (Stack, Column, etc.).
- Communication avec le reste de l’application via des
ValueChanged
et des interactions utilisateur. -
Conclusion
- CustomPainter et Canvas permettent de créer des UI et animations complexes au-delà des widgets standards.
- Ils offrent un contrôle total pour réaliser :
- Visualisations de données personnalisées.
- Animations uniques et engageantes.
- Interfaces utilisateur originales et optimisées.
- La clé : maîtriser les fondamentaux du dessin, optimiser les performances et combiner intelligemment avec Flutter.
class MonCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// Méthode principale pour dessiner
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// Détermine si le painter doit se redessiner
return true;
}
}
class MonPainter extends CustomPainter {
final double valeurAnimation;
MonPainter({required this.valeurAnimation});
@override
void paint(Canvas canvas, Size size) {
final centre = Offset(size.width / 2, size.height / 2);
final paint = Paint()..color = Colors.blue;
canvas.drawCircle(centre, 50.0 * valeurAnimation, paint);
}
@override
bool shouldRepaint(MonPainter oldDelegate) {
return oldDelegate.valeurAnimation != valeurAnimation;
}
}
class MonWidgetPersonnalise extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: MonPainter(valeurAnimation: 0.5),
size: Size(200, 200),
);
}
}
// Remplissage simple
final fillPaint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
// Contour
final strokePaint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 3.0;
// Dégradé
final gradientPaint = Paint()
..shader = LinearGradient(
colors: [Colors.yellow, Colors.orange],
).createShader(Rect.fromLTWH(0, 0, 200, 200));
class AnimationExample extends StatefulWidget {
@override
_AnimationExampleState createState() => _AnimationExampleState();
}
class _AnimationExampleState extends State<AnimationExample>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..repeat(reverse: true);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return CustomPaint(
painter: MonPainterAnimé(valeur: _animation.value),
size: Size(200, 200),
);
},
);
}
}