Appearance
Module 15 : Librairies JavaScript externes et Anime.js
Introduction
Ce module présente le concept des librairies JavaScript externes et la façon de les intégrer dans un projet via un CDN (Content Delivery Network). À travers la librairie Anime.js, vous apprendrez à créer des animations fluides et professionnelles sans avoir à tout coder manuellement, tout en conservant la structure de projet habituelle du cours.
Objectifs du cours
- Comprendre ce qu'est une librairie JavaScript externe et pourquoi en utiliser une
- Savoir intégrer une librairie via un CDN dans un projet HTML/CSS/JS
- Intégrer Anime.js dans un projet simple
- Produire différents types d'animations : déplacement, rebond, fondu, délai, combinaison de propriétés
Théorie
1 : Les librairies JavaScript externes
Définition
Une librairie JavaScript externe est un ensemble de fonctions et d'outils préconçus, créés par d'autres développeurs, que l'on peut inclure dans son propre projet pour accomplir certaines tâches plus facilement et rapidement.
Contexte d'utilisation
Certaines opérations courantes en développement web sont complexes à implémenter soi-même : tableaux de données interactifs, animations avancées, glisser-déposer (drag and drop), graphiques, etc. Plutôt que de repartir de zéro, on peut intégrer une librairie qui résout déjà ce problème.
Exemples de librairies populaires et leurs usages :
| Librairie | Usage principal |
|---|---|
| Anime.js | Animations JavaScript avancées |
| Chart.js | Graphiques et visualisations de données |
| SortableJS | Glisser-déposer (drag and drop) |
| DataTables | Tableaux interactifs (tri, recherche, pagination) |
| Swiper | Carrousels et sliders tactiles |
Points importants
- Chaque librairie possède sa propre documentation officielle à consulter
2 : Le CDN (Content Delivery Network)
Définition
Un CDN est un réseau de serveurs distribués géographiquement qui héberge des fichiers (JavaScript, CSS, images, etc.) et les livrent rapidement à l'utilisateur depuis le serveur le plus proche. Inclure une librairie via un CDN signifie qu'on ne télécharge pas la librairie localement : on pointe directement vers son URL publique.
Le principal avantage d'utiliser un CDN est la simplicité : il suffit d'ajouter une balise <script> dans le HTML pour inclure la librairie, sans avoir à gérer les fichiers localement.
Comment inclure une librairie via CDN
On ajoute simplement une balise <script> dans le fichier HTML, avant les scripts qui utiliseront cette librairie.
html
<!-- Librairie externe chargée en premier -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<!-- Nos propres fichiers JS chargés ensuite -->
<script src="js/scripts.js"></script>Important : L'ordre des balises
<script>dans le HTML est crucial. La librairie externe doit toujours être déclarée avant les scripts qui l'utilisent, sans quoi le navigateur ne reconnaîtra pas les fonctions de la librairie.
3 : Exemple d'une librairie externe : Anime.js
Définition
Anime.js est une librairie JavaScript légère qui permet de créer des animations fluides sur des éléments HTML en modifiant leurs propriétés CSS (position, opacité, couleur, rotation, etc.) selon une ligne du temps configurable.
Contexte d'utilisation
Anime.js est utile lorsque les animations CSS simples (transition ou @keyframes) ne suffisent plus : enchaînement d'animations, délais échelonnés sur plusieurs éléments, contrôle programmatique (démarrer, mettre en pause, rejouer).
Syntaxe de base
La fonction principale est anime({...}). On lui passe un objet de configuration :
javascript
anime({
targets: '#mon-element', // L'élément à animer (sélecteur CSS ou objet DOM)
translateX: 250, // Propriété à animer et valeur cible
duration: 1000, // Durée en millisecondes
easing: 'easeInOutQuad' // Courbe d'accélération
});Propriétés les plus utilisées
| Propriété | Description | Exemple |
|---|---|---|
targets | Élément(s) à animer | '#boite', '.carte' |
translateX | Déplacement horizontal (px) | 250 |
translateY | Déplacement vertical (px) | -100 |
rotate | Rotation | '1turn', '45deg' |
scale | Mise à l'échelle | 1.5 |
opacity | Opacité (0 à 1) | [0, 1] |
backgroundColor | Couleur de fond | '#e74c3c' |
duration | Durée en millisecondes | 1000 |
delay | Délai avant le départ (ms) | 500 |
easing | Courbe d'accélération | 'easeOutBounce' |
loop | Répétition | true, 3 |
direction | Sens de l'animation | 'alternate' |
Pour toute la documentation sur Anime.js (v3), consultez : https://animejs.com/v3/documentation/
Valeurs d'easing fréquentes
| Valeur | Effet |
|---|---|
'linear' | Vitesse constante |
'easeInOutQuad' | Accélération douce au départ et à l'arrivée |
'easeOutBounce' | Rebond à l'arrivée |
'easeOutElastic' | Effet élastique à l'arrivée |
'easeInOutSine' | Courbe sinusoïdale douce |
'spring(1, 80, 10, 0)' | Physique de ressort personnalisable |
4 : Intégrer Anime.js dans un projet simple
Structure du projet
mon-projet/
├── index.html
├── css/
│ └── styles.css
└── js/
└── scripts.jsDans index.html — inclusion du CDN
Le CDN d'Anime.js doit être placé avant votre propre fichier JS, idéalement juste avant la fermeture de </body> :
html
<!-- Anime.js via CDN (doit être chargé avant scripts.js) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<!-- Votre propre fichier JS -->
<script src="js/scripts.js"></script>Exemole code HTML
html
<button id="btn-animer">Animer</button>
<div id="div1">
<h2>Div 1</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Consectetur, quia!</p>
<img src="https://placehold.co/200x200" alt="Placeholder Image">
</div>Dans scripts.js — utilisation avec init()
javascript
function animer() {
anime({
targets: '#ma-boite',
translateX: 200,
duration: 1000,
easing: 'easeInOutQuad'
});
}
function init() {
document.getElementById('btn-animer').addEventListener('click', animer);
}
addEventListener('load', init);5 : Anime.js avec plusieurs fichiers JavaScript
Contexte d'utilisation
Dans un projet réel, vous aurez souvent plusieurs fichiers JavaScript : l'un pour la logique du site, un autre pour les animations, etc. Il faut s'assurer que le CDN est chargé avant tous ces fichiers.
Structure du projet avec plusieurs fichiers JS
mon-projet/
├── index.html
├── css/
│ └── styles.css
└── js/
├── app.js ← Logique principale du site
└── animations.js ← Animations avec Anime.jsDans index.html — ordre d'inclusion
html
<!-- 1. Anime.js CDN en premier -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<!-- 2. Vos fichiers JS dans l'ordre souhaité -->
<script src="js/app.js"></script>
<script src="js/animations.js"></script>Dans app.js — code existant du site
javascript
function afficherMessage() {
document.getElementById('message').textContent = 'Bienvenue sur le site !';
}
function init() {
document.getElementById('btn-message').addEventListener('click', afficherMessage);
}
addEventListener('load', init);Dans animations.js — animations Anime.js
javascript
function animerTitre() {
anime({
targets: '#titre-principal',
translateY: [-30, 0],
opacity: [0, 1],
duration: 800,
easing: 'easeOutQuad'
});
}
function init() {
animerTitre();
}
addEventListener('load', init);Note : Chaque fichier peut avoir sa propre fonction
init()et son propreaddEventListener('load', init). Le navigateur appellera les deux au chargement de la page, sans conflit. Chaqueinitest locale à son fichier et s'exécutera indépendamment.
Exemples d'animations avec Anime.js
Attention : les exemples suivants utilisent la syntaxe d'Anime.js 3.x et peuvent ne pas fonctionner avec les versions plus récentes. Assurez-vous d'utiliser la version 3.x du CDN pour tester ces exemples :
https://animejs.com/v3/documentation/
Déplacement horizontal simple
Anime un élément qui se déplace de 250px vers la droite au clic.
HTML
html
<div class="boite" id="boite-deplacement"></div>
<button id="btn-deplacement">Déplacer</button>CSS
css
.boite {
width: 80px;
height: 80px;
background-color: #3498db;
border-radius: 8px;
margin-bottom: 10px;
}JavaScript
javascript
function deplacerHorizontal() {
anime({
targets: '#boite-deplacement',
translateX: 250
});
}
function init() {
document.getElementById('btn-deplacement').addEventListener('click', deplacerHorizontal);
}
addEventListener('load', init);Animation avec durée personnalisée
Même déplacement, mais ralenti à 2 secondes avec une vitesse linéaire.
JavaScript
javascript
function deplacerLentement() {
anime({
targets: '#boite-duree',
translateX: 300,
duration: 2000,
easing: 'linear'
});
}
function init() {
document.getElementById('btn-duree').addEventListener('click', deplacerLentement);
}
addEventListener('load', init);Effet "bounce" (rebond à l'arrivée)
L'élément monte puis rebondit à la fin de l'animation.
JavaScript
javascript
function animerBounce() {
anime({
targets: '#boite-bounce',
translateY: -150,
duration: 900,
easing: 'easeOutBounce'
});
}
function init() {
document.getElementById('btn-bounce').addEventListener('click', animerBounce);
}
addEventListener('load', init);Animation combinée (plusieurs propriétés simultanées)
Déplacement, rotation et changement de couleur en même temps.
JavaScript
javascript
function animationCombinee() {
anime({
targets: '#boite-combinee',
translateX: 220,
rotate: '1turn',
scale: 1.4,
backgroundColor: '#e74c3c',
duration: 1200,
easing: 'easeInOutQuad'
});
}
function init() {
document.getElementById('btn-combinee').addEventListener('click', animationCombinee);
}
addEventListener('load', init);Fade in (apparition progressive)
L'élément part d'une opacité de 0 (invisible) pour aller à 1 (visible).
HTML
html
<div class="panneau" id="panneau-fade">Contenu qui apparaît</div>
<button id="btn-fade">Faire apparaître</button>CSS
css
.panneau {
opacity: 0;
padding: 20px;
background-color: #2ecc71;
color: white;
border-radius: 8px;
width: 250px;
text-align: center;
margin-bottom: 10px;
}JavaScript
javascript
function fadein() {
anime({
targets: '#panneau-fade',
opacity: [0, 1],
duration: 1500,
easing: 'easeInOutSine'
});
}
function init() {
document.getElementById('btn-fade').addEventListener('click', fadein);
}
addEventListener('load', init);Animation de plusieurs éléments avec délai échelonné
Chaque élément démarre son animation avec un décalage de 150ms par rapport au précédent, grâce à anime.stagger().
HTML
html
<div class="boite-multi" id="boite-m1"></div>
<div class="boite-multi" id="boite-m2"></div>
<div class="boite-multi" id="boite-m3"></div>
<div class="boite-multi" id="boite-m4"></div>
<button id="btn-multi">Animer en cascade</button>CSS
css
.boite-multi {
width: 60px;
height: 60px;
background-color: #9b59b6;
border-radius: 6px;
margin-bottom: 8px;
}JavaScript
javascript
function animerEnCascade() {
anime({
targets: '.boite-multi',
translateX: 280,
delay: anime.stagger(150),
duration: 700,
easing: 'easeOutQuad'
});
}
function init() {
document.getElementById('btn-multi').addEventListener('click', animerEnCascade);
}
addEventListener('load', init);Note :
anime.stagger(150)calcule automatiquement un délai croissant pour chaque élément ciblé : le 1er démarre à 0ms, le 2e à 150ms, le 3e à 300ms, etc.
Démonstration complète
Galerie animée avec Anime.js
Objectif
Créer une page avec une liste de cartes et un panneau de contrôle. Le fichier JS unique gère à la fois les interactions utilisateur (sélection/compteur) et les animations Anime.js.
Structure du projet VS Code :
mon-projet/
├── index.html
├── css/
│ └── styles.css
└── js/
└── script.js (logique + animations Anime.js)index.html
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Galerie animée - Anime.js</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1 id="titre-principal">Galerie animée</h1>
<div id="controles">
<button id="btn-entree">Animer l'entrée</button>
<button id="btn-reset">Réinitialiser</button>
<p>Cartes sélectionnées : <span id="compteur">0</span></p>
</div>
<div id="galerie">
<div class="carte" id="carte-1">
<img src="https://placehold.co/200x140/3498db/ffffff?text=Carte+1" alt="Carte 1">
<p>Carte 1</p>
</div>
<div class="carte" id="carte-2">
<img src="https://placehold.co/200x140/e74c3c/ffffff?text=Carte+2" alt="Carte 2">
<p>Carte 2</p>
</div>
<div class="carte" id="carte-3">
<img src="https://placehold.co/200x140/2ecc71/ffffff?text=Carte+3" alt="Carte 3">
<p>Carte 3</p>
</div>
<div class="carte" id="carte-4">
<img src="https://placehold.co/200x140/9b59b6/ffffff?text=Carte+4" alt="Carte 4">
<p>Carte 4</p>
</div>
</div>
<!-- Anime.js CDN — doit être avant script.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>css/styles.css
css
body {
font-family: Arial, sans-serif;
padding: 20px;
background: #f0f0f0;
}
h1 {
color: #333;
opacity: 0;
}
#controles {
display: flex;
gap: 10px;
margin: 20px 0;
align-items: center;
}
button {
padding: 8px 16px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
#galerie {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.carte {
background: white;
border-radius: 8px;
padding: 10px;
text-align: center;
cursor: pointer;
opacity: 0;
transform: translateY(20px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.carte:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.carte.selectionnee {
border: 2px solid #e74c3c;
}
.carte img {
border-radius: 4px;
margin-bottom: 8px;
}
.carte p {
margin: 0;
font-weight: bold;
}js/script.js
javascript
var compteurSelection = 0;
function toggleSelection(event) {
var carte = event.currentTarget;
carte.classList.toggle('selectionnee');
if (carte.classList.contains('selectionnee')) {
compteurSelection = compteurSelection + 1;
} else {
compteurSelection = compteurSelection - 1;
}
document.getElementById('compteur').textContent = compteurSelection;
}
function animerEntree() {
anime({
targets: '#titre-principal',
opacity: [0, 1],
translateY: [-20, 0],
duration: 600,
easing: 'easeOutQuad'
});
anime({
targets: '.carte',
opacity: [0, 1],
translateY: [30, 0],
delay: anime.stagger(120),
duration: 700,
easing: 'easeOutQuad'
});
}
function reinitialiserAnimation() {
var cartes = document.getElementsByClassName('carte');
for (var i = 0; i < cartes.length; i++) {
cartes[i].classList.remove('selectionnee');
}
compteurSelection = 0;
document.getElementById('compteur').textContent = 0;
anime({
targets: '.carte',
opacity: 0,
translateY: 30,
duration: 400,
easing: 'easeInQuad'
});
}
function init() {
var cartes = document.getElementsByClassName('carte');
for (var i = 0; i < cartes.length; i++) {
cartes[i].addEventListener('click', toggleSelection);
}
document.getElementById('btn-entree').addEventListener('click', animerEntree);
document.getElementById('btn-reset').addEventListener('click', reinitialiserAnimation);
}
addEventListener('load', init);Résultat attendu
Au chargement, les cartes et le titre sont invisibles. Un clic sur « Animer l'entrée » fait apparaître le titre, puis les cartes en cascade du haut vers le bas. Les cartes sont cliquables pour les sélectionner (bordure rouge) et le compteur se met à jour. Le bouton « Réinitialiser » efface les sélections et les cartes disparaissent en fondu.
- Le titre apparaît avec un glissement depuis le haut
- Les 4 cartes apparaissent en cascade avec un délai de 120ms entre chacune
- Le clic sur une carte la sélectionne (bordure rouge) et incrémente le compteur
- Un seul fichier
script.jsgère toute la logique et les animations
Exercices pratiques
Exercice 1 : Balle rebondissante
Avant de commencer
Cet exercice nécessite d'inclure le CDN d'Anime.js dans votre fichier HTML avant votre propre script JS.
Énoncé
Créer une page avec un cercle coloré et trois boutons : « Rebondir », « Tourner » et « Réinitialiser ». Chaque bouton déclenche une animation différente sur le cercle.
Fichiers à créer
index.htmlcss/styles.cssjs/scripts.js
Consignes
- Créer un élément
divavec la classeballequi représente un cercle (utiliserborder-radius: 50%) - Inclure le CDN d'Anime.js avant votre fichier
scripts.js - Le bouton « Rebondir » anime la balle vers le haut (
translateY) avec un easingeaseOutBounce - Le bouton « Tourner » anime la balle avec une rotation de
1turnen 800ms - Le bouton « Réinitialiser » remet la balle à sa position et rotation initiales (
translateY: 0,rotate: 0) en 400ms
Exercice 2 : Menu animé à l'entrée
Énoncé
Créer une page de présentation dont les éléments du menu de navigation apparaissent en cascade au chargement de la page, avec un effet de glissement depuis la gauche.
Fichiers à créer
index.htmlcss/styles.cssjs/scripts.js
Consignes
- Créer une barre de navigation avec au moins 4 liens (
<a>) ayant tous la même classe (ex :.nav-lien) - Au chargement de la page (dans
init()), déclencher automatiquement une animation sur tous les liens - Chaque lien doit partir de
translateX: -80etopacity: 0pour aller à leur position et opacité naturelles - Utiliser
anime.stagger(100)pour échelonner les délais - Utiliser l'easing
easeOutQuadavec une durée de 600ms
Exercice 3 : Tableau de bord animé
Énoncé
Créer une page « tableau de bord » avec des cartes de statistiques (ex. : ventes, visites, abonnés, revenus). Un seul fichier JS gère la mise à jour des valeurs et les animations Anime.js.
Fichiers à créer
index.htmlcss/styles.cssjs/script.js(mise à jour des valeurs + animations Anime.js)
Consignes
- Créer 4 cartes avec un titre, une valeur numérique et une couleur distinctive (utiliser
placehold.cosi des images sont nécessaires) - Au clic sur un bouton « Actualiser », mettre à jour les valeurs numériques des cartes avec de nouvelles valeurs fixes
- Au chargement, animer l'apparition des cartes en cascade (fade in + translateY)
- Au survol d'une carte (
mouseover), lui appliquer une animation de mise à l'échelle (scale: 1.05) en 200ms - Au retrait du survol (
mouseout), remettre l'échelle à1en 200ms - S'assurer que le CDN d'Anime.js est chargé avant
script.jsdans le HTML
Correction
Correction Exercice 1
Voir le code complet
index.html
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Balle rebondissante - Anime.js</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1>Balle rebondissante</h1>
<div class="balle" id="balle"></div>
<div class="controles">
<button id="btn-rebondir">Rebondir</button>
<button id="btn-tourner">Tourner</button>
<button id="btn-reset">Réinitialiser</button>
</div>
<!-- Anime.js CDN — doit être avant script.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>css/styles.css
css
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 20px;
background: #f0f0f0;
}
h1 {
color: #333;
margin-bottom: 30px;
}
.balle {
width: 80px;
height: 80px;
background: #3498db;
border-radius: 50%;
margin: 30px auto;
}
.controles {
display: flex;
gap: 10px;
justify-content: center;
margin-top: 20px;
}
button {
padding: 10px 20px;
background: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #2980b9;
}js/scripts.js
javascript
function rebondir() {
anime({
targets: '#balle',
translateY: -150,
duration: 800,
easing: 'easeOutBounce'
});
}
function tourner() {
anime({
targets: '#balle',
rotate: '1turn',
duration: 800,
easing: 'easeInOutQuad'
});
}
function reinitialiser() {
anime({
targets: '#balle',
translateY: 0,
rotate: 0,
duration: 400,
easing: 'easeInOutQuad'
});
}
function init() {
document.getElementById('btn-rebondir').addEventListener('click', rebondir);
document.getElementById('btn-tourner').addEventListener('click', tourner);
document.getElementById('btn-reset').addEventListener('click', reinitialiser);
}
addEventListener('load', init);Explications
Cet exercice démontre l'utilisation basique d'Anime.js avec trois animations différentes : un rebond vertical avec
easeOutBounce, une rotation complète, et une remise à zéro. Chaque fonction anime une propriété différente de la balle (position verticale, rotation, ou les deux). L'ordre des scripts dans le HTML est crucial pour que Anime.js soit disponible.
Correction Exercice 2
Voir le code complet
index.html
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Menu animé - Anime.js</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<nav>
<ul>
<li><a href="#" class="nav-lien">Accueil</a></li>
<li><a href="#" class="nav-lien">À propos</a></li>
<li><a href="#" class="nav-lien">Services</a></li>
<li><a href="#" class="nav-lien">Contact</a></li>
</ul>
</nav>
<!-- Anime.js CDN — doit être avant script.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>css/styles.css
css
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f8f9fa;
}
nav {
background: #343a40;
padding: 1rem;
border-radius: 8px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 2rem;
justify-content: center;
}
nav a {
color: white;
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: background-color 0.3s;
opacity: 0;
transform: translateX(-80px);
}
nav a:hover {
background: #495057;
}js/script.js
javascript
function animerMenu() {
anime({
targets: '.nav-lien',
translateX: [0, 0],
opacity: [0, 1],
delay: anime.stagger(100),
duration: 600,
easing: 'easeOutQuad'
});
}
function init() {
animerMenu();
}
addEventListener('load', init);Explications
L'animation du menu utilise
anime.stagger(100)pour créer un effet d'entrée en cascade où chaque lien apparaît avec un décalage de 100ms. Les liens partent d'une position décalée vers la gauche (translateX: -80pxdans le CSS) et d'une opacité de 0, pour arriver à leur position finale. L'animation se déclenche automatiquement au chargement de la page dans la fonctioninit().
Correction Exercice 3
Voir le code complet
index.html
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tableau de bord animé - Anime.js</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1>Tableau de bord</h1>
<button id="btn-actualiser">Actualiser</button>
<div class="tableau-bord">
<div class="carte" id="carte-ventes">
<h3>Ventes</h3>
<div class="valeur" id="valeur-ventes">1250</div>
</div>
<div class="carte" id="carte-visites">
<h3>Visites</h3>
<div class="valeur" id="valeur-visites">8750</div>
</div>
<div class="carte" id="carte-abonnes">
<h3>Abonnés</h3>
<div class="valeur" id="valeur-abonnes">320</div>
</div>
<div class="carte" id="carte-revenus">
<h3>Revenus</h3>
<div class="valeur" id="valeur-revenus">15420</div>
</div>
</div>
<!-- Anime.js CDN — doit être avant script.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>css/styles.css
css
body {
font-family: Arial, sans-serif;
padding: 20px;
background: #f8f9fa;
text-align: center;
}
h1 {
color: #333;
margin-bottom: 20px;
}
#btn-actualiser {
padding: 10px 20px;
background: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-bottom: 30px;
}
#btn-actualiser:hover {
background: #218838;
}
.tableau-bord {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
max-width: 800px;
margin: 0 auto;
}
.carte {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
opacity: 0;
transform: translateY(30px);
cursor: pointer;
transition: box-shadow 0.3s;
}
.carte:hover {
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
}
.carte:nth-child(1) { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.carte:nth-child(2) { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.carte:nth-child(3) { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
.carte:nth-child(4) { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); }
.carte h3 {
color: white;
margin: 0 0 10px 0;
font-size: 18px;
}
.valeur {
font-size: 32px;
font-weight: bold;
color: white;
}js/script.js
javascript
function animerEntreeCartes() {
anime({
targets: '.carte',
opacity: [0, 1],
translateY: [30, 0],
delay: anime.stagger(150),
duration: 800,
easing: 'easeOutQuad'
});
}
function animerSurvolCarte(event) {
anime({
targets: event.currentTarget,
scale: 1.05,
duration: 200,
easing: 'easeOutQuad'
});
}
function animerSortieCarte(event) {
anime({
targets: event.currentTarget,
scale: 1,
duration: 200,
easing: 'easeOutQuad'
});
}
function actualiserValeurs() {
// Valeurs fixes pour la démonstration
const nouvellesValeurs = {
ventes: 1420,
visites: 9200,
abonnes: 385,
revenus: 17850
};
anime({
targets: '#valeur-ventes',
innerHTML: nouvellesValeurs.ventes,
duration: 500,
easing: 'easeOutQuad'
});
anime({
targets: '#valeur-visites',
innerHTML: nouvellesValeurs.visites,
duration: 500,
easing: 'easeOutQuad'
});
anime({
targets: '#valeur-abonnes',
innerHTML: nouvellesValeurs.abonnes,
duration: 500,
easing: 'easeOutQuad'
});
anime({
targets: '#valeur-revenus',
innerHTML: nouvellesValeurs.revenus,
duration: 500,
easing: 'easeOutQuad'
});
}
function init() {
animerEntreeCartes();
const cartes = document.getElementsByClassName('carte');
for (let i = 0; i < cartes.length; i++) {
cartes[i].addEventListener('mouseover', animerSurvolCarte);
cartes[i].addEventListener('mouseout', animerSortieCarte);
}
document.getElementById('btn-actualiser').addEventListener('click', actualiserValeurs);
}
addEventListener('load', init);Explications
Ce tableau de bord combine plusieurs concepts : animation d'entrée en cascade pour les cartes, animations au survol, et mise à jour animée des valeurs. L'animation des valeurs utilise
innerHTMLcomme propriété cible d'Anime.js pour créer un effet de compteur animé. Les cartes ont des couleurs de fond dégradées distinctives et réagissent au survol avec une mise à l'échelle.