Как запустить анимацию чисел, когда до них доскроллил?

В коде есть анимация чисел и функция, которая определяет видим ли объект. Теперь надо сделать так, чтобы анимация запускалась, когда числа видны на экране.

<html>
<head>
      <meta charset="utf-8">
      <title>Numbers</title>
</head>
<body>

<div style="width: 200px; height: 400px; background: red;"></div>

<div id="count1"></div>
<div id="count2"></div>
<div id="count3"></div>


<script>

//СЧИТАЛКА
const counterAnim = (qSelector, start = 0, end, duration = 1000) => {
    const target = document.querySelector(qSelector);
    let startTimestamp = null;
    const step = (timestamp) => {
        if (!startTimestamp) startTimestamp = timestamp;
        const progress = Math.min((timestamp - startTimestamp) / duration, 1);
        target.innerText = Math.floor(progress * (end - start) + start);
        if (progress < 1) {
            window.requestAnimationFrame(step);
        }
    };
    window.requestAnimationFrame(step);
};

//ВИДИМ ЛИ ОБЪЕКТ
function isInViewport(el) {
    const rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
};

//ВЫВОД
document.addEventListener("DOMContentLoaded", () => {
    counterAnim("#count1", 0, 23, 2000);
    counterAnim("#count2", 0, 64, 2000);
    counterAnim("#count3", 0, 320, 2000);
});

</script>


</body>


Ответы (1 шт):

Автор решения: Rudi

Можно использовать IntersectionObserver. В этом примере он отслеживает появление элемента с id=count3

var options = {
  threshold: 1
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#count3');

observer.observe(target);

function callback(entries, observer) {
  counterAnim("#count1", 0, 23, 2000);
  counterAnim("#count2", 0, 64, 2000);
  counterAnim("#count3", 0, 320, 2000);
}
<div style="width: 200px; height: 400px; background: red;"></div>

<div id="count1"></div>
<div id="count2"></div>
<div id="count3"></div>


<script>
  //СЧИТАЛКА
  const counterAnim = (qSelector, start = 0, end, duration = 1000) => {
    const target = document.querySelector(qSelector);
    let startTimestamp = null;
    const step = (timestamp) => {
      if (!startTimestamp) startTimestamp = timestamp;
      const progress = Math.min((timestamp - startTimestamp) / duration, 1);
      target.innerText = Math.floor(progress * (end - start) + start);
      if (progress < 1) {
        window.requestAnimationFrame(step);
      }
    };
    window.requestAnimationFrame(step);
  };

  //ВИДИМ ЛИ ОБЪЕКТ
  function isInViewport(el) {
    const rect = el.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  };
</script>

→ Ссылка