Модификации счетчика чисел для Zero и стандартного блока в Tilda

100000 руб.
1000000 руб.
А это - нет
Это число анимировано
Модификация для сайта на Тильде создает счетчик на обычный текстовый блок и Zero block в Тильда.

Я не знаю, зачем вам надо добавлять плавную анимацию чисел в обычный текстовый блок, например как тут → $ 1000000.
Но пускай будет. Если что, ее можно не включать - просто не указывайте класс «uc-animation-text» на блоке.
Но если надо, то: настройки блока → «CSS CLASS NAME» → и прописать «animation-text». Число при этом надо написать слитно в виде числа.

Для анимации чисел в Зеро блоке вы просто указываете CSS-класс на весь блок «uc-animation-num». То есть в Тильде нужно зайти в настройки блока → «CSS CLASS NAME» → и прописать «animation-num» (uc- само добавится).
Но учтите, в таком случае, все цифры внутри Zero block будут анимированы в виде счетчика.
Если надо, чтобы таймер установился только на одно число, то необходимо:
  1. Зайти в Контент Зеро блока
  2. Правой кнопкой мыши нажать на текстовый элемент с числом
  3. Задать ему класс «uc-animation-text» (теперь uc- надо прописать).

Инструкция:
  1. В блок с кодом добавили код ниже.
  2. В коде можно, следуя комментариям, поправить скорость анимации чисел до достижения верхнего порога (верхний порог числа указывается прямо в тексте вашего блока, так что в коде капаться не надо).
<!-- Модификации счетчика чисел. https://t.me/breeze_tilda -->

<script>
document.addEventListener("DOMContentLoaded", function () {

  var CLASS_ATOM = '.uc-animation-num .tn-atom'; // ← класс Zero Block
  var CLASS_TEXT = '.uc-animation-text'; // ← класс обычного блока
  var OFFSET = -50; // ← отступ, когда начинает срабатывать анимация
  var DURATION = 4000; // ← вот здесь менять время отсчета в миллисекундах
  var SEPARATOR = ' ';
  var SCROLL_DEBOUNCE = 50;
  var INIT_DELAY = 100;

  function formatNumber(num) {
    return Math.floor(num).toString().replace(/\B(?=(\d{3})+(?!\d))/g, SEPARATOR);
  }

  function isVisible(el) {
    var rect = el.getBoundingClientRect();
    return rect.top <= window.innerHeight + OFFSET && rect.bottom >= -OFFSET;
  }

  function easeInOut(p) {
    return p < 0.5 ? 2 * p * p : -1 + (4 - 2 * p) * p;
  }

  function animate(item) {
    if (item.hasAnimated) return;
    item.hasAnimated = true;

    var startTime = Date.now();

    function tick() {
      var progress = Math.min((Date.now() - startTime) / DURATION, 1);
      var current = item.target * easeInOut(progress);
      item.el.textContent = item.prefix
        ? item.prefix + formatNumber(current) + item.suffix
        : formatNumber(current);
      if (progress < 1) requestAnimationFrame(tick);
    }

    requestAnimationFrame(tick);
  }

  function buildAtomItems() {
    var items = [];

    document.querySelectorAll(CLASS_ATOM).forEach(function (el) {
      var text = el.textContent;
      var match = text.match(/[\d,.]+/);
      if (!match) return;

      var target = parseFloat(match[0].replace(/[,]/g, ''));
      if (isNaN(target)) return;

      var start = text.indexOf(match[0]);
      items.push({
        el: el,
        target: target,
        prefix: text.substring(0, start),
        suffix: text.substring(start + match[0].length),
        hasAnimated: false,
      });

      el.textContent = text.substring(0, start) + '0' + text.substring(start + match[0].length);
    });

    return items;
  }

  function buildTextItems() {
    var items = [];

    document.querySelectorAll(CLASS_TEXT).forEach(function (container) {
      var walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, null, false);
      var textNodes = [];

      while (walker.nextNode()) {
        textNodes.push(walker.currentNode);
      }

      textNodes.forEach(function (node) {
        var text = node.nodeValue;
        var parts = text.split(/(\d+)/);
        if (parts.length <= 1) return;

        var frag = document.createDocumentFragment();

        parts.forEach(function (part) {
          if (/^\d+$/.test(part)) {
            var span = document.createElement('span');
            span.textContent = '0';
            items.push({
              el: span,
              target: parseInt(part, 10),
              prefix: null,
              suffix: null,
              hasAnimated: false,
            });
            frag.appendChild(span);
          } else {
            frag.appendChild(document.createTextNode(part));
          }
        });

        node.parentNode.replaceChild(frag, node);
      });
    });

    return items;
  }

  function checkAll(items) {
    items.forEach(function (item) {
      if (!item.hasAnimated && isVisible(item.el)) animate(item);
    });
  }

  var items = buildAtomItems().concat(buildTextItems());
  var scrollTimer;

  window.addEventListener('scroll', function () {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(function () { checkAll(items); }, SCROLL_DEBOUNCE);
  }, { passive: true });

  window.addEventListener('resize', function () { checkAll(items); });

  setTimeout(function () { checkAll(items); }, INIT_DELAY);
});

</script>
Больше кода для Tilda в ТГ-канале
Поблагодари за код - подпишись https://t.me/breeze_tilda