Javascript - 그리드 레이아웃 이미지 교체 효과
핀터레스트에서 영감을 받아 3x3 그리드 레이아웃에서 이미지를 순차적으로 교체하는 웹 효과를 자바스크립트로 구현한 예시입니다. 더미 데이터는 photo.json에 저장되어 있습니다.자바스크립트에서는 이미지를 순차적으로 교체하는 스크립트를 구현했습니다.
Reference
핀터레스트에서 재미있는 효과를 봤습니다.
3X3의 그리드 레이아웃에서 이미지가 순차적으로 교체되는 효과인데, 단순하면서도 인상적입니다. 영상에서 많이 쓰이는 효과지만, 자바스크립트를 이용하면 웹에서도 비교적 수월하게 구현할 수 있습니다.
Preview
아래 영상은 실제로 구현했을 때 모습입니다. 순차적으로 이미지가 교체되는데, 약간의 딜레이를 주어서 다음 그리드 부분에서는 한 박자씩 늦게 교차되도록 구현합니다.
HTML
html은 아주 단순합니다. app이라는 id를 갖고 있는 main 태그에 내용이 삽입되도록 javascript에서 모든 부분을 제어합니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Photo Changer</title>
</head>
<body>
<main id="app"></main>
<script src="main.js" defer async type="module" ></script>
</body>
</html>
photo.json
간단한 더미 데이터를 마련해서 json 파일에 담아두었습니다. 이미지의 출처는 모두 pexels.com
에서 가져왔습니다.
{
"data": [
{
"id": 1,
"url": "https://images.pexels.com/photos/58997/pexels-photo-58997.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
},
{
"id": 2,
"url": "https://images.pexels.com/photos/4043573/pexels-photo-4043573.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
},
{
"id": 3,
"url": "https://images.pexels.com/photos/9335893/pexels-photo-9335893.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
},
{
"id": 4,
"url": "https://images.pexels.com/photos/9291125/pexels-photo-9291125.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
}
]
}
SCSS
스타일 시트 부분도 그다지 복잡하지 않은 구성입니다. 기본적인 배치는 grid
를 이용해서 4x3 그리드를 만들고 있습니다.
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap');
*{
margin:0;
padding:0;
box-sizing: border-box;
}
html,body{
width: 100%;
height: 100%;
font-family: 'Poppins', sans-serif;
}
body{
display: flex;
justify-content: center;
align-items: center;
}
img{
width: 100%;
max-width: 100%;
height: 100%;
object-fit: cover;
border:0;
}
#app{
--col : 4;
--row: 3;
--size: 800px;
display: grid;
grid-template-columns: repeat(var(--col), 1fr);
grid-template-rows: repeat(var(--row),1fr);
width:var(--size);
height:var(--size);
border-radius: 1vw;
overflow: hidden;
position: relative;
&::before,&::after{
width:100%;
height: 100%;
position: absolute;
top:0;
left:0;
}
&::before{
content: '';
background-color: hsla(220,50%,20%,0.5);
}
&::after{
display: flex;
align-items: center;
justify-content: center;
font-size: 5rem;
color: white;
text-transform: uppercase;
content: 'Happy Dogs'
}
figure{
height: 100%;
overflow:hidden;
}
}
Javascript
import photos from "./photo.json" assert {type: 'json'}
const {data} = photos
const delay = 500
// 주요 기능: 이미지와 이미지 변환기를 설정합니다.
const main = () => {
// app element를 가져옵니다.
const app = document.getElementById('app')
// app element 내부의 이미지 개수를 9개로 설정합니다.
setImages(app, 12)
// app element 내부의 모든 이미지를 가져와서 이미지 변환기에 설정합니다.
setChanger(Array.from(app.querySelectorAll('img')))
}
// 이미지들을 설정하는 함수
const setImages = (app, count) => {
// 이미지 개수만큼 반복
for (let i = 0; i < count; i++) {
// figure와 image 엘리먼트 생성
const figure = document.createElement('figure')
const image = document.createElement('img')
// 이미지를 figure에 추가
figure.appendChild(image)
// app에 figure 추가
app.appendChild(figure)
image.src= data[0].url; // 초기 이미지 설정
}
}
// 이미지 배열을 받아 타이머를 이용해 이미지를 변경하는 함수
const setChanger = (imageArray) => {
let timer; // 타이머 변수
imageArray.forEach((item, index) => {
timer = setTimeout(() => imageChanger(item,data,delay), delay * index); // 지연 시간에 따라 이미지 변경
});
};
/**
* 이미지를 주어진 데이터 배열의 url로 변경하는 함수
* @param {HTMLImageElement} image - 변경할 이미지 요소
* @param {Array} data - 이미지 URL을 포함하는 데이터 배열
* @param {number} delay - 이미지 변경 간격 (밀리초)
*/
const imageChanger = (image, data, delay) => {
let index = 0; // 데이터 배열의 인덱스
const timer = setInterval(() => {
if (index < data.length) {
image.src = data[index].url; // 이미지 소스 변경
index++; // 다음 데이터로 이동
} else {
clearInterval(timer); // 타이머 중지
}
}, delay);
}
window.addEventListener('load', main)
대략적인 작업의 흐름은 아래와 같습니다.
photo.json
에서 이미지 링크들을 가져와서 반복문을 이용해 배치하고, 순차적으로 교체하는 일을 하는 스크립트입니다.
delay
상수에서 이미지가 교체되는 빠르기
와 지연시간
을 모두 같이 쓰고 있습니다. 필요하다면 두 부분으로 나누는 것도 나쁘지 않습니다.
main
함수 안에서는 setImages
와 setChanger
함수를 호출하고 있는데, 각각 이미지를 배치하고, 그 배치된 이미지마다 순차적으로 교체되는 일을 하도록 작성했습니다.
setChanger
함수에서는 배치된 이미지들의 배열을 넘겨받아서, 그 배열 안에서 img
태그를 하나하나 꺼내 다시 imageChanger
함수로 각각의 이미지를 넘겨주는데, 그 안에서 setInterval
비동기 함수를 이용해 img
태그의 이미지를 순차적으로 교체하는 일을 합니다.
교체할 이미지는 photo.json
에서 가져옵니다.
그리고 마지막으로 전체적인 작업을 실행할 수 있는 main
함수를 호출하는 것으로 스크립트를 마무리합니다.
Comments ()