Effet de défilement numérique avec CSS3 Transition

La création d'un effet de competur ou d'odomètre dynamique repose sur la manipulation de la position verticale d'une série de chiffres alignés. En utilisant la propriété CSS transition, il est possible d'animer le passage d'une valeur à une autre de manière fluide et professionnelle.

Concept de fonctionnement

Le principe de base consiste à créer des colonnes verticales contenant les chiffres de 0 à 9. Chaque colonne est encapsulée dans un conteneur avec un overflow: hidden. Pour afficher un chiffre spécifique, on déplace la colonne vers le haut (via la propriété top ou transform: translateY) d'une distance correspondant à la hauteur d'un chiffre multipliée par sa valeur.

Structure HTML de base

Le conteneur doit avoir une hauteur définie, car celle-ci servira de référence pour le calcul du décalage des chiffres.

<!-- Conteneur principal pour l'animation -->
<div id="compteur-dynamique" class="numeric-scroller"></div>

<style>
    .numeric-scroller {
        height: 50px;
        background-color: #222;
        border-radius: 4px;
        overflow: hidden;
        display: inline-block;
    }
</style>

Implémentatoin du script d'animation

Voici une réimplémentation optimisée utilisant jQuery pour gérer la manipulation du DOM et les transitions CSS3.

/**
 * @param {string} selector - Sélecteur CSS du conteneur
 * @param {Object} params - Configuration (itemWidth, fontSize, textColor)
 */
function DigitScroller(selector, params) {
    this.wrapper = $(selector);
    this.settings = params;
    
    this.wrapper.css({
        position: "relative",
        padding: "0",
        display: "flex"
    });

    this.digitHeight = this.wrapper.height();
    this.digitTemplate = '<span class="digit-column" style="position:relative; top:0;">' +
        '<i>0</i><i>1</i><i>2</i><i>3</i><i>4</i>' +
        '<i>5</i><i>6</i><i>7</i><i>8</i><i>9</i><i>.</i>' +
        '</span>';
}

DigitScroller.prototype.renderValue = function(newValue) {
    const valStr = newValue.toString();
    const currentDigits = this.wrapper.find(".digit-column").length;

    // Ajustement du nombre de colonnes si nécessaire
    if (valStr.length > currentDigits) {
        for (let i = 0; i < (valStr.length - currentDigits); i++) {
            this.wrapper.prepend(this.digitTemplate);
        }
    } else if (valStr.length < currentDigits) {
        for (let i = 0; i < (currentDigits - valStr.length); i++) {
            this.wrapper.find(".digit-column").first().remove();
        }
    }

    // Application des styles aux colonnes et aux chiffres
    const columns = this.wrapper.find(".digit-column");
    columns.css({
        width: this.settings.itemWidth + "px",
        transition: "top 0.8s ease-in-out"
    });

    columns.find("i").css({
        height: this.digitHeight + "px",
        lineHeight: this.digitHeight + "px",
        textAlign: "center",
        fontSize: this.settings.fontSize + "px",
        color: this.settings.textColor,
        display: "block",
        fontStyle: "normal"
    });

    // Animation vers la nouvelle position
    for (let j = 0; j < valStr.length; j++) {
        let char = valStr[j];
        let offset = 0;
        
        if (char === ".") {
            offset = -(10 * this.digitHeight);
        } else {
            offset = -(parseInt(char) * this.digitHeight);
        }

        columns.eq(j).css("top", offset + "px");
    }
};

Exemple d'utilisation complète

L'exemple suivant montre comment initialiser le compteur et mettre à jour sa valeur de façon périodique.


<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Démo Compteur Animé</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

    <div class="container" style="padding: 50px;">
        <div id="mon-compteur" style="height: 60px;"></div>
    </div>

    <script>
        $(document).ready(function() {
            // Initialisation
            const scroller = new DigitScroller("#mon-compteur", {
                itemWidth: 35,
                fontSize: 42,
                textColor: "#3498db"
            });

            let score = 4500;
            
            // Mise à jour initiale
            scroller.renderValue(score);

            // Simulation d'une mise à jour en temps réel
            setInterval(function() {
                score += Math.floor(Math.random() * 500);
                scroller.renderValue(score);
            }, 2500);
        });
    </script>
</body>
</html>

Cette approche est particulièrement efficace car elle délègue le travail d'animation au moteur de rendu du navigateur via les transiitons CSS, ce qui assure une performance optimale même sur les terminaux mobiles, tout en conservant une logique de contrôle simple en JavaScript.

Étiquettes: CSS3 jQuery Animation web-performance frontend

Publié le 19 juin à 21h49