동료들에게 발표했던 '카드 뒤집기 초간단 실습 예제'포스팅입니다! 프로젝트를 하면서 가장 인상 깊고 재밌는 기능들도 같이 정리했습니다! 실습 예제부터 시작합니다😉
이 실습은 HTML, CSS, JSON으로만 구현한 간단한 실습 예제입니다! 이 포스팅에서는 HTML과 CSS 코드만 가져오겠습니다. 위의 링크로 가서 클론 후 직접 작업해보세요!
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="img/pikachu.png">
<title>✨스프라이트 기법 써보기✨</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<ul class="list-card"></ul>
<script>
const $cardList = document.querySelector('.list-card');
// json 데이터 가져오기
const getCardData = fetch("card.json")
.then((res) => res.json())
.then((data) => cardData(data))
function cardData(data) {
// 랜덤 배열 생성
data.sort(() => Math.random() - 0.5);
// 데이터 출력
data.forEach((card) => {
const template = `
<li class="card">
<div class="back-card"></div>
<div class="front-card" style="background-position: ${card.position.x}px ${card.position.y}px;"></div>
</li>
`;
// HTML에 추가하기
// $cardList.innerHTML += template;
// innerHtml보다 작업이 덜 드므로 빠르다.
// https://developer.mozilla.org/ko/docs/Web/API/Element/insertAdjacentHTML
$cardList.insertAdjacentHTML('beforeend', template);
})
}
</script>
</body>
</html>
먼저 json 파일을 fetch
해서 데이터를 가져온 후, cardData 함수를 실행해서 데이터를 보내주고, forEach
로 받아온 데이터를 출력해봅시다!
여기서 포인트가 background-position
값에 json 파일에 있는 position 값을 넣어주는 것이지요. json 파일을 보면 position의 x, y값들이 잘 들어가 있습니다.
이걸로 이미지 스프라이트 기법을 이용한 데이터 뿌리기 끝입니다! 정말 초초간단하죠?
* {
margin: 0;
padding: 0;
list-style: none;
}
.list-card {
width: 50%;
display: grid;
grid-template-columns: repeat(4, 1fr);
justify-items: center;
margin: 50px auto;
gap: 20px;
}
.card {
position: relative;
outline: 4px solid #00479d;
/* 3D 효과가 적용된 요소의 자식 요소에 3D 효과가 전달 */
transform-style: preserve-3d;
width: 100%;
max-width: 150px;
max-height: 205px;
min-width: 100px;
min-height: 136px;
aspect-ratio: 193 / 264;
border-radius: 10px;
background-color: #ffeea2;
transition: all 1s;
}
.card:hover {
transform: rotateY(180deg);
}
.back-card {
background-image: url("../img/card-back.png");
background-size: contain;
width: 100%;
height: 100%;
background-repeat: no-repeat;
/* 요소의 뒷쪽에서 앞면이 보이게 할지 정하는 속성 */
backface-visibility: hidden;
}
.front-card {
position: absolute;
top: 50%;
left: 50%;
margin: 0 auto;
background-image: url("../img/pokemon.png");
background-color: #ffeea2;
width: 100px;
height: 100px;
display: block;
transform: translate(-50%, -50%) rotateY(180deg);
backface-visibility: hidden;
transition: all 1s;
}
CSS 코드를 보면 자주 사용하지 않았던 속성 몇 개가 보이시죠? 카드 뒤집기를 구현할 때 가장 중요한 기능이니, 밑에서 더 알아보도록 하겠습니다!
let num = [1, 2, 3, 4, 5];
num.sort(() => Math.random() - 0.5);
양수와 음수를 무작위로 반환하는 판별식을 이용해서 배열의 정렬 기능에 대입해 배열의 요소를 무작위로 바꿉니다.
Array.sort()
Math.random()
0 ~ 1 미만의 값을 리턴 → 양수값만 출력 → 랜덤값이 한 방향으로만 편향 → 그것을 막기 위해서 0.5를 뺌
반환받은 랜덤한 값에서 0.5를 빼면 음수 값과 양수 값을 무작위로 반환합니다.
Array.sort()
에 필요한 리턴값은 -1 과 1만 필요합니다. (즉, 음수나 양수 중 하나만 리턴하면 됨)
단점 : Array.sort()
함수는 위와 같은 용도로 만들어진 메서드가 아니기 때문에 순열의 빈도수가 균일하게 나오지 않습니다.
배열 끝 요소부터 시작해 앞으로 하나씩 나아가면서 해당 요소 앞에 있는 임의의 요소와 해당 요소를 바꿔치기하는 알고리즘
위의 함수보다 더욱 고른 결과값을 획득할 수 있을 뿐만 아니라 피셔-예이츠 알고리즘은 ‘정렬' 연산도 없기 때문에 성능상 이점 또한 가지고 있습니다.
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
// 1, 2, 3으로 만들 수 있는 모든 순열의 빈도를 세줍니다.
let count = {
123: 0,
132: 0,
213: 0,
231: 0,
321: 0,
312: 0,
};
for (let i = 0; i < 1000000; i++) {
let array = [1, 2, 3];
shuffle(array);
count[array.join("")]++;
}
// 만들 수 있는 모든 순열의 생성 빈도를 세서 출력해줍니다.
for (let key in count) {
alert(`${key}: ${count[key]}`);
}
$cardList.innerHTML += template;
// vs
$cardList.insertAdjacentHTML("beforeend", template);
innerHTML
insertAdjacentHTML
transform-style
CSS 속성은 요소의 자식이 3D 공간에 배치되는지 또는 요소의 평면에서 병합되는지 여부를 설정합니다.preserve-3d
3D 효과가 적용된 요소의 자식 요소에 3D 효과가 전달
멋있어요 희수님!!