JSFiddle - React, Tailwind, and code Playground

HTML

<div class="wrapper">
  <div class="clouds">
    <div class="cloud" style="top: 120px; left: 275px"></div>
    <div class="cloud" style="top: 76px; left: 175px"></div>         <div class="cloud" style="top: 258px; left: 205px"></div>
    <div class="cloud" style="top: 204px; left: 45px"></div>
    <div class="cloud" style="top: 40px; left: 175px"></div>
    <div class="cloud" style="top: 186px; left: 83px"></div>
    <div class="cloud" style="top: 137px; left: 70px"></div>
    <div class="cloud" style="top: 37px; left: 50px"></div>
    <div class="cloud" style="top: 170px; left: 90px"></div>
  </div>
</div>

CSS

.wrapper {
  margin-top: 100vh;
  overflow: hidden;
  height: 300px;
  width: 300px;
  background-color: grey;
  position: relative;
}
.cloud {
  position: absolute;
  width: 10px;
  height: 10px;
  background-color: #000;
}

JavaScript

let offset = 100; // Нужна для того, чтобы анимация запускалась не сразу же после прокрутки до элемента
let wrapperTop = getCoords(document.querySelector('.wrapper')).top + offset;
let array = document.querySelectorAll('.cloud');
let range = 2; // Сделал её специально, чтобы блоки двигались с разной скоростью, можете указать её как 1
let interval;

array.forEach((el) => {
  el.step = Math.ceil(Math.random() * range);
})

window.addEventListener('scroll', () => {
  let windowPos = window.innerHeight + window.scrollY;
  if (windowPos >= wrapperTop)
    if (!interval) {
      interval = setInterval(swim, 10);
    }
})

function swim() { // "Заставляет" плавать наши облака
  array.forEach((el) => {
    let posLeft = parseInt(getComputedStyle(el).left);
    el.style.left = posLeft - el.step + 'px';
    if (posLeft < -el.offsetWidth) {
      el.style.left = el.offsetParent.offsetWidth + el.offsetWidth + 'px';
    }
  })
}

function getCoords(elem) { // Получение координат относительно документа
  var box = elem.getBoundingClientRect();

  return {
    top: box.top + pageYOffset,
    left: box.left + pageXOffset
  };

}