먼저 코드는 다음과 같습니다.
import './style-intersectionObserver.css'
const divApp = document.querySelector("#app")
if(divApp) {
  for(let i=0; i<20; i++) {
    const div = document.createElement("div")
    div.innerHTML = (i+1).toString()
    divApp.append(div)
  }
  
  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if(entry.isIntersecting) {
        entry.target.classList.add("visible")
      } else {
        entry.target.classList.remove("visible")
      }
    })
  }, {
    threshold: 0
  })
  const divList = divApp.querySelectorAll("div")
  divList?.forEach((div) => observer.observe(div))
}
스타일은 다음과 같구요.
body {
  margin: 0;
}
#app {
  overflow-y: auto;
  position: fixed;
  background-color: rgb(45, 46, 47);
  background-image: 
    linear-gradient(to right, rgb(35, 36, 37) 1px, transparent 1px), 
    linear-gradient(to bottom, rgb(35, 36, 37) 1px, transparent 1px);
  background-size: 32px 32px;
  width: 100%;
  height: 100vh;
}
#app div {
  color: white;
  font-size: 5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px auto;
  height: 160px;
  width: 160px;
  border-radius: 10%;
  background-color: black;
  border: 2.5px solid white;
  transition: all 0.5s ease-in-out;
  transform: rotate(-90deg) scale(0.1);
  opacity: 0;
}
#app div.visible {
  transform: rotate(0deg) scale(1);
  opacity: 1;
}
실행 결과는 다음과 같습니다.

