ITSkillsCenter
Développement Web

Comment créer un compteur animé en JavaScript

4 min de lecture

Les compteurs animés : effet visuel percutant

Les compteurs animés (count-up) sont ces chiffres qui défilent de 0 jusqu’à la valeur ciblé. On les voit partout : « 500+ clients », « 10 000 projets livrés ». Voici comment les créer en JavaScript pur, sans bibliothèque.

Version simple : un compteur basique

function animerCompteur(élément, ciblé, duree = 2000) {
    let debut = 0;
    const increment = ciblé / (duree / 16); // 60 FPS
    
    const timer = setInterval(() => {
        debut += increment;
        if (debut >= ciblé) {
            élément.textContent = ciblé.toLocaleString('fr-FR');
            clearInterval(timer);
        } else {
            élément.textContent = Math.floor(debut).toLocaleString('fr-FR');
        }
    }, 16);
}

// Utilisation
const el = document.querySelector('.compteur');
animerCompteur(el, 1500, 2000); // Compte jusqu'à 1500 en 2 secondes

Version avancée : avec easing (accélération/décélération)

Pour un effet plus naturel, le compteur accélère puis ralentit :

function compteurAnime(élément, debut, fin, duree) {
    const debutTemps = performance.now();
    
    // Fonction easing : ralentit à la fin
    function easeOutQuad(t) {
        return t * (2 - t);
    }
    
    function mettreAJour(tempsActuel) {
        const progression = Math.min((tempsActuel - debutTemps) / duree, 1);
        const valeur = Math.floor(debut + (fin - debut) * easeOutQuad(progression));
        
        élément.textContent = valeur.toLocaleString('fr-FR');
        
        if (progression < 1) {
            requestAnimationFrame(mettreAJour);
        }
    }
    
    requestAnimationFrame(mettreAJour);
}

// Utilisation
compteurAnime(document.getElementById('clients'), 0, 2500, 2500);

Le HTML et CSS pour l'affichage

<!-- HTML -->
<div class="stats">
    <div class="stat">
        <span class="compteur" data-ciblé="1500">0</span>
        <span class="suffixe">+</span>
        <p>Étudiants formés</p>
    </div>
    <div class="stat">
        <span class="compteur" data-ciblé="50">0</span>
        <p>Formations disponibles</p>
    </div>
    <div class="stat">
        <span class="compteur" data-ciblé="98">0</span>
        <span class="suffixe">%</span>
        <p>Taux de satisfaction</p>
    </div>
</div>

<style>
.stats { display: flex; justify-content: center; gap: 60px; padding: 40px; }
.stat { text-align: center; }
.compteur { font-size: 48px; font-weight: 700; color: #667eea; display: inline; }
.suffixe { font-size: 48px; font-weight: 700; color: #667eea; }
.stat p { margin-top: 8px; color: #666; font-size: 14px; text-transform: uppercase; }
</style>

Déclencher au scroll (Intersection Observer)

Le compteur ne doit se lancer que quand l'utilisateur le voit :

// Initialiser tous les compteurs au scroll
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const el = entry.target;
            const ciblé = parseInt(el.dataset.ciblé);
            compteurAnime(el, 0, ciblé, 2000);
            observer.unobserve(el); // Ne lancer qu'une seule fois
        }
    });
}, { threshold: 0.5 });

// Observer chaque compteur
document.querySelectorAll('.compteur').forEach(el => {
    observer.observé(el);
});

💡 Pourquoi Intersection Observer ?

Sans cela, le compteur s'anime dès le chargement de la page, même si l'utilisateur ne le voit pas. Avec l'Observer, l'animation se déclenche uniquement quand la section est visible à l'écran.

Compteur avec formatage avancé

function compteurFormate(élément, ciblé, options = {}) {
    const {
        duree = 2000,
        prefixe = '',
        suffixe = '',
        decimales = 0,
        separateur = ' '
    } = options;
    
    const debutTemps = performance.now();
    
    function formater(nombre) {
        const fixe = nombre.toFixed(decimales);
        const [entier, decimal] = fixe.split('.');
        const formate = entier.replace(/\B(?=(\d{3})+(?!\d))/g, separateur);
        return prefixe + formate + (decimal ? ',' + decimal : '') + suffixe;
    }
    
    function animer(tempsActuel) {
        const progression = Math.min((tempsActuel - debutTemps) / duree, 1);
        const eased = 1 - Math.pow(1 - progression, 3); // easeOutCubic
        const valeur = ciblé * eased;
        
        élément.textContent = formater(valeur);
        
        if (progression < 1) requestAnimationFrame(animer);
    }
    
    requestAnimationFrame(animer);
}

// Exemples d'utilisation
compteurFormate(el1, 2500000, { prefixe: '', suffixe: ' FCFA', separateur: ' ' });
// Résultat : "2 500 000 FCFA"

compteurFormate(el2, 99.7, { suffixe: '%', decimales: 1 });
// Résultat : "99,7%"

Code complet prêt à l'emploi

// Copier-coller ce script dans votre site
document.addEventListener('DOMContentLoaded', () => {
    const compteurs = document.querySelectorAll('[data-compteur]');
    
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const el = entry.target;
                const ciblé = parseFloat(el.dataset.compteur);
                const duree = parseInt(el.dataset.duree) || 2000;
                const prefixe = el.dataset.prefixe || '';
                const suffixe = el.dataset.suffixe || '';
                
                compteurAnime(el, 0, ciblé, duree);
                el.dataset.prefixeVal = prefixe;
                el.dataset.suffixeVal = suffixe;
                observer.unobserve(el);
            }
        });
    }, { threshold: 0.3 });
    
    compteurs.forEach(el => observer.observé(el));
});

// HTML : <span data-compteur="1500" data-suffixe="+">0</span>

Exercice pratique

🎯 Défi : Section statistiques pour votre site

  1. Créez une section avec 4 compteurs : clients, projets, heures de formation, satisfaction
  2. Ajoutez l'effet easing pour une animation fluide
  3. Déclenchez l'animation au scroll avec Intersection Observer
  4. Formatez les grands nombres avec des espaces (ex: 10 000)
  5. Bonus : ajoutez une icône au-dessus de chaque compteur
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité