Utilities

Compteur (Counterup)

<script>
class CounterUp {
  constructor(element, options = {}) {
    this.element = element;

    let parent = element.parentElement;
    let timeAttribute = parent ? parent.getAttribute('js-util-counterup-time') : null;
    let time = timeAttribute ? parseInt(timeAttribute, 10) : options.time || 2000;

    this.options = Object.assign(
      {
        time: time,
        delay: 10,
      },
      options
    );

    this.origValue = element.textContent;

    let loopElement = element.closest('[js-util-counterup-loop]');
    let loopAttribute = loopElement ? loopElement.getAttribute('js-util-counterup-loop') : null;
    this.shouldLoop = loopAttribute === 'true';

    this.nums = [];
    this.init();
  }

  counterUpper() {
    this.nums = [];
    const divisions = this.options.time / this.options.delay;
    let num = this.origValue;
    const isComma = /[0-9]+,[0-9]+/.test(num);
    num = num.replace(/,/g, '');
    const isInt = /^[0-9]+$/.test(num);
    const isFloat = /^[0-9]+\.[0-9]+$/.test(num);
    const decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;

    for (let i = divisions; i >= 1; i--) {
      let newNum = parseInt((num / divisions) * i);

      if (isFloat) {
        newNum = parseFloat((num / divisions) * i).toFixed(decimalPlaces);
      }

      if (isComma) {
        while (/\d+(\d{3})/.test(newNum.toString())) {
          newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
        }
      }

      this.nums.unshift(newNum);
    }

    this.element.textContent = this.origValue;
    this.element.textContent = '0';

    const updateNumber = () => {
      this.element.textContent = this.nums.shift();
      if (this.nums.length) {
        setTimeout(updateNumber, this.options.delay);
      }
    };

    setTimeout(updateNumber, this.options.delay);
  }

  init() {
    const observer = new IntersectionObserver(
      (entries, observer) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            this.counterUpper();
            if (!this.shouldLoop && entry.isIntersecting) {
              observer.disconnect();
            }
          }
        });
      },
      { threshold: 1.0 }
    );

    observer.observe(this.element);
  }
}

document.addEventListener('DOMContentLoaded', function () {
  let timeCounter = document
    .querySelector('[js-util-counterup-time]')
    .getAttribute('js-util-counterup-time');
  document.querySelectorAll('[js-util-counterup]').forEach((element) => {
    new CounterUp(element, { delay: 100, time: timeCounter });
  });
});</script>

Etape 1 - Ajouter le script sur la page ou le projet Webflow

<!-- Scripts by Justa | Counter Up -->
<script src="https://cdn.jsdelivr.net/npm/@justaa/scripts/dist/util/counterup.js"></script>
<script>
class CounterUp {
  constructor(element, options = {}) {
    this.element = element;

    let parent = element.parentElement;
    let timeAttribute = parent ? parent.getAttribute('js-util-counterup-time') : null;
    let time = timeAttribute ? parseInt(timeAttribute, 10) : options.time || 2000;

    this.options = Object.assign(
      {
        time: time,
        delay: 10,
      },
      options
    );

    this.origValue = element.textContent;

    let loopElement = element.closest('[js-util-counterup-loop]');
    let loopAttribute = loopElement ? loopElement.getAttribute('js-util-counterup-loop') : null;
    this.shouldLoop = loopAttribute === 'true';

    this.nums = [];
    this.init();
  }

  counterUpper() {
    this.nums = [];
    const divisions = this.options.time / this.options.delay;
    let num = this.origValue;
    const isComma = /[0-9]+,[0-9]+/.test(num);
    num = num.replace(/,/g, '');
    const isInt = /^[0-9]+$/.test(num);
    const isFloat = /^[0-9]+\.[0-9]+$/.test(num);
    const decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;

    for (let i = divisions; i >= 1; i--) {
      let newNum = parseInt((num / divisions) * i);

      if (isFloat) {
        newNum = parseFloat((num / divisions) * i).toFixed(decimalPlaces);
      }

      if (isComma) {
        while (/\d+(\d{3})/.test(newNum.toString())) {
          newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
        }
      }

      this.nums.unshift(newNum);
    }

    this.element.textContent = this.origValue;
    this.element.textContent = '0';

    const updateNumber = () => {
      this.element.textContent = this.nums.shift();
      if (this.nums.length) {
        setTimeout(updateNumber, this.options.delay);
      }
    };

    setTimeout(updateNumber, this.options.delay);
  }

  init() {
    const observer = new IntersectionObserver(
      (entries, observer) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            this.counterUpper();
            if (!this.shouldLoop && entry.isIntersecting) {
              observer.disconnect();
            }
          }
        });
      },
      { threshold: 1.0 }
    );

    observer.observe(this.element);
  }
}

document.addEventListener('DOMContentLoaded', function () {
  let timeCounter = document
    .querySelector('[js-util-counterup-time]')
    .getAttribute('js-util-counterup-time');
  document.querySelectorAll('[js-util-counterup]').forEach((element) => {
    new CounterUp(element, { delay: 100, time: timeCounter });
  });
});</script>
Copier

Etape 2 - Ajouter les attributes correspondants

Div - Définir la durée de l'animation

Paragraph - Identifier chaque chiffre dynamique

Div - identifier si le compteur doit être joué en boucle

Tuto, template & scripts

<script>
class CounterUp {
  constructor(element, options = {}) {
    this.element = element;

    let parent = element.parentElement;
    let timeAttribute = parent ? parent.getAttribute('js-util-counterup-time') : null;
    let time = timeAttribute ? parseInt(timeAttribute, 10) : options.time || 2000;

    this.options = Object.assign(
      {
        time: time,
        delay: 10,
      },
      options
    );

    this.origValue = element.textContent;

    let loopElement = element.closest('[js-util-counterup-loop]');
    let loopAttribute = loopElement ? loopElement.getAttribute('js-util-counterup-loop') : null;
    this.shouldLoop = loopAttribute === 'true';

    this.nums = [];
    this.init();
  }

  counterUpper() {
    this.nums = [];
    const divisions = this.options.time / this.options.delay;
    let num = this.origValue;
    const isComma = /[0-9]+,[0-9]+/.test(num);
    num = num.replace(/,/g, '');
    const isInt = /^[0-9]+$/.test(num);
    const isFloat = /^[0-9]+\.[0-9]+$/.test(num);
    const decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;

    for (let i = divisions; i >= 1; i--) {
      let newNum = parseInt((num / divisions) * i);

      if (isFloat) {
        newNum = parseFloat((num / divisions) * i).toFixed(decimalPlaces);
      }

      if (isComma) {
        while (/\d+(\d{3})/.test(newNum.toString())) {
          newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
        }
      }

      this.nums.unshift(newNum);
    }

    this.element.textContent = this.origValue;
    this.element.textContent = '0';

    const updateNumber = () => {
      this.element.textContent = this.nums.shift();
      if (this.nums.length) {
        setTimeout(updateNumber, this.options.delay);
      }
    };

    setTimeout(updateNumber, this.options.delay);
  }

  init() {
    const observer = new IntersectionObserver(
      (entries, observer) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            this.counterUpper();
            if (!this.shouldLoop && entry.isIntersecting) {
              observer.disconnect();
            }
          }
        });
      },
      { threshold: 1.0 }
    );

    observer.observe(this.element);
  }
}

document.addEventListener('DOMContentLoaded', function () {
  let timeCounter = document
    .querySelector('[js-util-counterup-time]')
    .getAttribute('js-util-counterup-time');
  document.querySelectorAll('[js-util-counterup]').forEach((element) => {
    new CounterUp(element, { delay: 100, time: timeCounter });
  });
});</script>
Copier

Etape 2 - Ajuster le code pour votre besoin

Copié dans le presse-papiers
Logo Justa

Progressez sur Webflow

Oops! Une erreur s'est produite lors de la soumission du formulaire.