# 3d-carousel

Main·2023년 3월 24일
0

# 3d-carousel 만들기

• carousel은 다양한 종류가 있음
• 플러그인을 사용하면 쉽게 구현할 수 있다.
(owl-carousel, bootstrap-carousel, swiper-carousel 등)

수업에서 배운 perspective 속성과 perserve-3d 속성을 응용하여 3d-carousel를 직접 구현해 보기

#### 구현 포인트

• prespective 속성과 preserve-3d 속성
• transformZ 길이 적용
<div class="carousel">
<div class="carousel-card">Card1</div>
<div class="carousel-card">Card2</div>
<div class="carousel-card">Card3</div>
<div class="carousel-card">Card4</div>
<div class="carousel-card">Card5</div>
<div class="carousel-card">Card6</div>
<div class="carousel-card">Card7</div>
<div class="carousel-card">Card8</div>
<div class="carousel-card">card9</div>
</div>

### 2 ) 원근감 효과를 위해 carousel의 부모요소를 만들고 perspective 속성을 부여한다.

 <div class="scene">
<div class="carousel">
<div class="carousel-card">Card1</div>
<div class="carousel-card">Card2</div>
<div class="carousel-card">Card3</div>
<div class="carousel-card">Card4</div>
<div class="carousel-card">Card5</div>
<div class="carousel-card">Card6</div>
<div class="carousel-card">Card7</div>
<div class="carousel-card">Card8</div>
<div class="carousel-card">card9</div>
</div>
</div>
.scene {
width: 210x;
height: 140px;
position: relative;
/* 원근감을 위해 */
perspective: 1800px;
margin: 0 auto;
margin-top: 100px;
}

### 3 ) carousel의 자식요소에 3d 효과를 주기위해 perserve-3d 속성을 부여한다.

.carousel {
width: 100%;
height: 100%;
position: absolute;
/* perspective가 적용된 자식 요소들에 3D 효과 원근감*/
transform-style: preserve-3d;
transition: all .5s;
}
.carousel-card {
position: absolute;
/* 셀 배치를 약간씩 떨어뜨림*/
width: 190px;
height: 120px;
left: 10px;
top: 10px;
transition: all .5s;
font-size: 30px;
color: #fff;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
}

angle = 360 / carousel-card 개수

.carousel-card:nth-child(1) { transform: rotateY(  0deg); }
.carousel-card:nth-child(2) { transform: rotateY( 40deg); }
.carousel-card:nth-child(3) { transform: rotateY( 80deg); }
.carousel-card:nth-child(4) { transform: rotateY(120deg); }
.carousel-card:nth-child(5) { transform: rotateY(160deg); }
.carousel-card:nth-child(6) { transform: rotateY(200deg); }
.carousel-card:nth-child(7) { transform: rotateY(240deg); }
.carousel-card:nth-child(8) { transform: rotateY(280deg); }
.carousel-card:nth-child(9) { transform: rotateY(320deg); }

r 만큼의 길이를 transformZ 속성을 주어 carousel-card를 떨어뜨린다.

.carousel-card:nth-child(1) { transform: rotateY(  0deg) translateZ(288px); }
.carousel-card:nth-child(2) { transform: rotateY( 40deg) translateZ(288px); }
.carousel-card:nth-child(3) { transform: rotateY( 80deg) translateZ(288px); }
.carousel-card:nth-child(4) { transform: rotateY(120deg) translateZ(288px); }
.carousel-card:nth-child(5) { transform: rotateY(160deg) translateZ(288px); }
.carousel-card:nth-child(6) { transform: rotateY(200deg) translateZ(288px); }
.carousel-card:nth-child(7) { transform: rotateY(240deg) translateZ(288px); }
.carousel-card:nth-child(8) { transform: rotateY(280deg) translateZ(288px); }
.carousel-card:nth-child(9) { transform: rotateY(320deg) translateZ(288px); }

=> css 대신 javascript를 이용하여 carousel-card 배치를 동적으로 할당

const carouselCard = documnet.queryselector(".carousel-card");
const rataeAngle = 360 / carouselCard.length;
const radian = (ratateAngle / 2) * Math.PI / 180;
const tz = (210 / 2) / Math.tan(radin);

carouselCard.forEach((el,idx)=>el.style.transform = rotateY(${ratateAngle*idx}deg) translateZ(${tz}px));

📌 r를 구하는 방법 => 삼각비를 이용한다.

• r = (밑변의 길이) / tan(angle)
• 여기서 구하려는 r = (card의 width / 2 ) / Math.tan(angle에 해당하는 radian)
• radian = (angle / 2) * (Math.PI / 180)

### 7 ) carousel를 위에서 구한 각도 만큼 더하면서 Y축으로 회전 시키면 카드가 바뀌는 효과가 나타난다.

casrousel angle = angle * 현재 카드의 index

### 추가 ) x축, y축를 축 전환시켜 전환효과를 줄 수 있다.

• carousel, carousel-card 들의 translate 축 변경
• X축으로 회전시
transform = translateY() => transform = translateX()로 변경
• Y축으로 회전시
transform = translateX() => transform = translateY()로 변경
• r 길이가 바뀌어야함 => r = (card-height / 2) / Math.tan(Radin)
• X축으로 회전 시
card-width 값 대신 card-height 값 대입
• Y축으로 회전 시
card-height 값 대신 card-width 값 대입
• classList row 확인을 통해 축을 구분해줌

### 최종 코드

함께 개선하는 개발자 / 현재 노션으로 이동하였습니다.