CSS3 : 애니메이션 transform3D, perspective

우리는 평소에 z축이 적용된 작품들을 수 없이 접합니다. 아래 카페를 표현한 그림을 보면

좌측이미지가 더욱 입체감있는 느낌을 느낄수 있는데 이 것은 z축을 사용한 이미지이기 때문입니다.

   

 

이 원근감 있는 효과를 우리는 Transform와 perspective 속성을 이용하여

웹 페이지에도 적용할 수 있습니다.

animation@keyframes과 transition까지 활용하면 애니메이션을 제작할 수도 있겠죠?

 

 

3D 개념

3D 애니메이션을 진행하기 위해서는 먼저 3D 개념을 이해하는 것이 중요합니다.

먼저 (아래) x, y, z 축에 대한 그림을 참고해봅시다.

수평/수직 이동은 2차원 좌표에서 실행하는 일로 x축과 y축을 이용합니다.

여기서 입체감있는 원근감을 추가하려면 3차원 좌표에서 z축을 추가로 이용해야 합니다.

 

x축, y축은 상하좌우로 단순 이동/크기/회전이 되는 축 개념이라면

z축은 원근감개념으로 위치를 이동 시 보고 있는 사람 쪽으로 다가오거나 멀어진다고 생각해보세요.

z축 기준으로 원근감 설정되어 점점 다가오는 팝업창들

 


 

원근감 개념(투영점, 소실점)

 

개념1. 투영점(Projection point)이란? 3D 원근감 초점(관찰자 시점)

d가 작을 수록(위 이미지) 시야가 커져 3D 공간 요소가 확실하게 원형으로 보입니다.

(위) 이미지출처 https://tympanus.net/codrops/css_reference/perspective/

3D 원근감을 적용하려면 먼저 투영점(perspective)속성을 설정해야합니다.

perspective는 사용자 시점 기준 거리를 설정하는 CSS 속성입니다.

perspective의 값에 따라서 얼마나 멀리떨어져있고 가까이있는지 차이를 설정할 수 있습니다.

 

 

개념2. 소실점(vanishing point)이란? 원근감 끝점

원근감이 적용된 물체가 있을 때 해당 물체는 멀리 떨어져있을 수록 작아보입니다.

이 때 아주 작아져 보이지 않을 정도의 끝 부분에 임의의 점을 찍는 것을 '소실점'이라고 부릅니다.

지평선 상의 끝으로 갈 수록 사라지는(소실) 점이라고 해서 소실점이라고 부릅니다.

 

 


 

transform-3D 적용하기(부모 기준 적용)

3D 속성을 주고 싶다면 먼저 원근감을 적용하고자 하는 요소와 그 부모로 대상을 구분해야 합니다.

<div class="perspective">
    <div class="box"></div>
</div>

대상을 확실히 구분했다면 먼저 부모요소에 다음(아래)과 같이 명령을 적용하세요.

 

transform-style:perserve-3d 속성은 3D속성적용 대상의 부모에 주는 명령으로 

부모 내에 자식 요소를 3차원 객체로 인식할 수 있게 하는 속성입니다.

 

perspective:500px 속성은 (위) 투영점 설명 첨부그림에서 설명한 사람과 화면 상의 거리를 뜻합니다.

값이 작을 수록 극적으로 대상을 보여줍니다. px단위를 주로 사용합니다. (500px은 임의의 값입니다.)

.perspective {
  transform-style:perserve-3d;
  perspective:500px;
}

 

부모에 3차원 객체 명령과 투영점 설정을 했다면 이제 자식 요소에 원하는 transform 값을 입력하세요.

같은 rotateX 값이더라도 perspective값(거리)에 따라 결과가 달라집니다.(아래 그림1-1 참고)

.perspective .box {
    transform:rotateX(65deg)
}

그림1-1

See the Pen transform3D-example1 by yuna122212 (@yuna122212) on CodePen.

 

 


 

 

transform-3D 적용하기(자식 기준 적용)

3D 원근감 속성을 적용하고 싶은 대상이 2개 이상이거나 개별로 원근감(persepective)를 주고 싶을 경우는 자식에 직접 적용하기도 합니다.

<div class="wrap">
  <div class="box box1">box</div>
  <div class="box box2">box</div>
</div>

 

(아래)  CSS를 보시면 부모(.wrap)에는 별다른 원근감 속성이 적용되지 않은 것을 볼 수 있습니다.

하지만 자식 .box1, .box2를 보시면 transform속성으로 먼저 원근감 값이 개별로 들어가 있고

그에 따라 rotateX가 들어가 원근감 적용에 따라 어떻게 회전되어있는지 차이를 볼 수 있습니다.

.wrap {background:yellow; width:100px;}
.wrap .box {
    width:100px; height:100px;
    background:rgba(255,0,0,0.5);
}
.wrap .box1 {transform:perspective(500px) rotateX(45deg)}
.wrap .box2 {transform:perspective(100px) rotateX(45deg)}

 

See the Pen transform3D-example2 by yuna122212 (@yuna122212) on CodePen.

 


 

transform-3D 적용하기(부모 vs 자식 누구한테 줘야할까?)

앞에서 확인한 것처럼 3D는 부모와 자식 모두에게 적용할 수 있습니다.

그런데 위 예제까지 해보면 2개의 별 차이가 없는 걸 볼 수 있습니다. 그럼 도대체 누구한테 주라는걸까요?

 

여기서 더 많은 자식 리스트를 생성하여 부모와 자식에 적용한 차이를 확인해봅시다.

 

HTML(동일)

<div class="wrap">
  <div class="box">box</div>
  <div class="box">box</div>
  <div class="box">box</div>
  <div class="box">box</div>
</div>

 

부모 기준 CSS(아래)

.wrap {
  background:yellow; 
  width:500px;
  display:flex; 
  justify-content:space-between;
  
  transform-style:perserve-3d;
  perspective:200px;
}
.wrap .box {
  width:100px; height:100px;
  background:rgba(255,0,0,0.5);
  
  transform:rotateX(45deg)
}

 

자식 기준 CSS(아래)

.wrap {
  background:yellow; 
  width:500px;
  display:flex; 
  justify-content:space-between;
}
.wrap .box {
  width:100px; height:100px;
  background:rgba(255,0,0,0.5);
  
  transform:perspective(200px) rotateX(45deg)
}

See the Pen transform3D-example3 by yuna122212 (@yuna122212) on CodePen.

 

위 CSS와 같이 입력하면 기준에 따라 위/아래 순서로 부모-자식의 적용 차이를 볼 수 있습니다.

부모와 자식에 속성을 넣은 것뿐이고 원근감이나 회전값은 모두 같은데도 확실한 결과 차이가 보이죠?

 

 

 

바로 기준으로 하는 소실점의 차이 때문에 그렇습니다.

부모를 기준으로 하는 perspective는 소실점이 부모기준 한 곳으로 정해져있기 때문에 

원근감이 서로 동일한 소실점을 보며 배치가 되어있습니다.

 

하지만 개별 자식에게 perspective를 설정한 경우는 개별 소실점이 별도 설정되어 

형제요소들끼리 서로 영향을 주지 않는 위와는 다른 결과가 보이게 되는 것입니다.

 

 

그럼 다시한번 확인해봅시다.

perspective는 부모vs자식 누구한테 쓰는게 좋을까요?

 

정답은 없으며 제작하는 결과에 따라 2가지 특징을 고려하여 선택하면 됩니다!

 

 


 

backface-visibility(이면가시성)

화면 모든 요소는 우리가 보는 '앞면'만 존재하며 회전으로 뒤를 보려고 하면 뒷면은 비어있는 것을 확인할 수 있습니다.

(아래) 그림에서 첫번째 줄 모습이 아무것도 설정하지 않았을 때 기본 backface-visibility(이면가시성)의 모습입니다.

요소의 뒷면에 아무것도 존재하지 않기 떄문에 화면에서 사라져 버립니다.

 

 

 

3D 동작을 원할 시 (위) 두번째 줄 그림처럼 뒷면을 보게 하고 싶다면 backface-visibility속성을 적용합니다.

적용 대상은 transform 속성이 들어가는 대상이 됩니다.

 

1. HTML을 준비합니다.

<div class="wrap">
    <div class="box front">Front</div>
</div>
<div class="wrap">
    <div class="box back">Back</div>
</div>

 

2. 부모요소가 되는 .wrap에 원근감 객체 인식공간을 만들어줍니다.

.wrap { 
  width:200px; height:50px;
  transform-style:preserve-3d; 
}

 

3. 움직이는 자식 요소에 나머지 3d 속성을 입력합니다.

Front, Back 기본 모습

.box {
  width:100%; height:100%;
  transition:1s;
}
.front {
  background: red;
  transform: rotateY(0deg);
  backface-visibility: hidden;
}

.back {
  background: green;
  transform: rotateY(0deg);
  backface-visibility:visible;
}

 

4. 상태선택자:hover와 함께 마우스 오버 시 적용되는 속성을 추가로 작성합니다.

크로스브라우징에 따라 -webkit-, -moz- 등을 함께 작성해야합니다.

Front에 마우스 오버 시 결과
Back에 마우스 오버 시 결과

.wrap:hover .box {
  transform: rotateY(180deg);
}

See the Pen transform3D-example4 by yuna122212 (@yuna122212) on CodePen.

 

 

  Comments,     Trackbacks