
웹사이트를 보다 보면 화면 스크롤을 내리면 특정 이미지나 글씨가 자연스럽게 나오는 애니메이션을 본 적 있을 것이다
만드는 방법을 정리해 보겠다
대표적인 예시 영상이다 특정요소가 화면에 보이면 자연스럽게 애니메이션 하듯이 나온다
1. IntersectionObserver 관찰자 사용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
background-color: black;
height: 5000px;
}
div{
color: white;
text-align: center;
margin-top: 1300px;
opacity: 0;
transition: all 0.5s; /*0.5초속도로 변경됨 화면 변경있을때*/
}
img{
height: 400px;
}
</style>
</head>
<body>
<div>
<h1>치킨,피자,탕수육,짜장면</h1>
</div>
<div>
<img src="a.jpg" alt="">
</div>
<div>
<h1>파이썬,자바스크립트,c언어</h1>
</div>
<div>
<h1>에스파,아이브,엔믹스,블랙핑크</h1>
</div>
<script>
//화면에 요소들이 보이고 안보이고를 테스트함 new IntersectionObserver
let ob = new IntersectionObserver((e)=>{
//화면에 등장할시 이 안에 있는 코드가 작동함
//화면에 요소가 등장하거나 사라질 때 모두 실행
e.forEach((a)=>{
console.log(a)//a는 감지하고있는 요소 observer로 넣은 div태그들
if(a.isIntersecting){
//isIntersecting은 요소가 보일때를를 감지해줌
//a요소가 화면에 보이면 true 안보이면 false
a.target.style.opacity = 1;
console.log(a.intersectionRatio);
//화면에 요소가 몇 퍼센트만큼 나왔는지 수치가 나옴
}
else{
//화면에서 살아질대
a.target.style.opacity = 0;
}
})
})
let div = document.querySelectorAll("div")
ob.observe(div[0]) //내가 원하는 html요소를 감지해서 화면에서 등장하는 감시함
ob.observe(div[1])
ob.observe(div[2])
ob.observe(div[3])
</script>
</body>
</html>
애니메이션 할 html 요소를 queryselectorAll을 사용해서 변수에 담아주고
div로 내가 감지하려고 하는 요소를 observe() 메서드 안에 넣어준다
2.threshold로 감지하기
let observer = new IntersectionObserver(함수, { threshold: 0.1 });
observer로 감지할려고 설정해둔 요소가 화면에 몇 퍼센트 보이느냐에 따라 함수가 실행되는 메서드이다
예를 들어 threshold가 0.5이면 html요소가 반만 보이면 안에 함수가 실행하게 된다
3. 예제
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IntersectionObserver Animation</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
min-height: 200vh;
}
.box {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.8s ease, transform 0.8s ease; /* 애니메이션 효과 */
}
.box.plus {
opacity: 1;
transform: translateY(0);
}
.container {
max-width: 600px;
margin: 100px auto;
display: flex;
flex-direction: column;
gap: 220px;
}
.content {
height: 150px;
background: #373653;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
}
</style>
</head>
<body>
<div class="container">
<div class="box content">content 1</div>
<div class="box content">content 2</div>
<div class="box content">content 3</div>
<div class="box content">content 4</div>
</div>
<script>
// IntersectionObserver 생성
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('plus'); // 클래스 추가
observer.unobserve(entry.target); // 한 번만 실행
}
});
}, { threshold: 0.1 });
// 모든 .box 요소를 관찰
document.querySelectorAll('.box').forEach(box => observer.observe(box));
</script>
</body>
</html>
unobserve 사용하여 화면에 한번 보인 애니메이션은 감지를 해지시켜 여러 번 스크롤을 넘길 때마다 애니메이션이 작동 안 하게 한다