티스토리 뷰

html과 css를 이용하여 3D 애니메이션을 만들어 보겠습니다.

 

 

 

 
 

 

 

 

 

 

저는 repl.it 개발도구를 이용하였습니다. 군대에서 이만한 게 없단 말이야 goormide 도 있지만.. 이건 너무 어렵고..

playcode.io는 별로 정감이 안감.... 

우선 첫 번째로 원하는 이미지 몇 개를 골라서 repl.it 목록에 추가해줍니다.

이미지 추가사진

상업적으로 이용할 생각 없습니다.. 만약 저작권 문제가 된다면 바로 내리겠습니다....

저는 최근 다섯번째계절로 컴백한 오 마이걸의 아린으로 이미지를 넣으려고 합니다.

사진은 https://www.pinterest.co.kr/ 에서 가져왔습니다.

html  코드만 아래처럼 해주었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Arine3D Animation</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <script src="script.js"></script>
 
                <div class ="rotating-box"> 
                        <div class ="single-rb">
 
                            
                            <div class="front-side">
                                    <img src="Arine6.jpg" alt="" >
                            </div>
 
 
                                        <div class="back-side">
                               <img src="Arine2.jpg" alt=""  >
                                        </div>
 
 
                                        <div class="left-side">
                                                 <img src="Arine4.jpg" alt=""  >
                                        </div>
 
 
 
                                        <div class="right-side">
                                                <img src="Arine3.jpg" alt=""   >
                                        </div>
 
 
 
 
                                        <div class="top-side"></div>
                                        <div class="bottom-side"></div>
                        </div>
                </div>
 
 
 
 
 
  </body>
</html>
 
cs

 박스틀을 이루는 rotating 클래스가 전체 클래스의 상위 클래스가 되도록 합니다. 

다음 은 이미지들을 관리할 수 있도록 single-rb 클래스를 선언해 주었고. 

정육면체를 이루도록 할것이기 때문에 상하좌우 앞뒤  top  , bottom , left , right , front , rear로 선언해줍니다.

이후에 회전하는 육면체를 형성 할거기 때문에 이미지 태그를 이용해서 미리 준비해둔 이미지들을 원하는 위치 클래스에 넣어주었습니다.

현재까지의 작업은 그냥 이미지가 화면상에 배치되기만 합니다.

자 이제 html에서의 작업은 끝났습니다. css 코드로 가서 이 이미지들을 가지고 재밌게 놀아볼 겁니다.

미리  css 코드를 링크해둡니다.   

<link href="style.css" rel="stylesheet" type="text/css" />

 

1
2
3
4
5
6
7
8
9
10
11
12
13
.rotating-box{
 
  width : 400px;
 
  height : 400px;
 
  margin: 10px auto;
 
  perspective: 800px;
 
}
 
 
cs

전체 화면의 기준이 될 rotating-box 의 너비 높이를 보기좋게 맞출겁니다.

CSS 3D transform 메소드에 perspective가 있다. perspective 란 3D 요소에 원근감을 표현할 때 사용할 픽셀 수를 지정해주는 것이다.

작게 해줄수록 그물체의 중앙에서 보는 느낌이 들것이다 . 작게 해줄수록 중심에 있는 느낌이 들것이다. 아직 배우고 있는 단계라 아닐수도 있습니다!

그러나 아직은 어떠한 애니메이션이나 동작이 없기때문에 웹상에서의 변화는 없다.

margin 10px auto ; 로 인해서 사진이 가운데로 정렬되었다.

margin 속성 값을 auto로 설정하면, 웹 브라우저가 수평 방향 마진(margin) 값을 자동으로 설정된다.

즉,  해당 HTML 요소의 왼쪽과 오른쪽 마진을 자동으로 설정되어 그 결과 해당 요소는 그 요소를 포함하고 있는 부모(parent) 요소의 정중앙에 위치하게 된다. 여기서 부모 요소는 rating-box이다.

 

 

다음으로 single-rb 클래스이다.

1
2
3
4
5
6
7
8
.single-rb{
    width: 400px;
    animation: rotate 15s linear infinite;
    transform-style:preserve-3d;
    margin-top: 120px; 
}
 
 
 
s

 

CSS3 이 나오면서 animation 속성을 사용하여 요소의 현재 스타일을 다른 스타일로  변화시킬 수 있게 되었다.

속성으로 @keyframes animation을 써야 한다.

@keyframes 규칙

CSS에서 애니메이션 효과를 사용하기 위해서는 우선 애니메이션에 대한 키 프레임(keyframe)을 정의해야 한다.

키 프레임(keyframe)에는 특정한 시간에 해당 요소가 가져야 할 CSS 스타일을 명시해야 한다.

@keyframes 규칙 안에  CSS 스타일을 설정해 놓으면, 해당 요소의 스타일은 특정 시간까지 현재 스타일에서 설정해 놓은 새로운 스타일로 천천히 변화할 것입니다.

애니메이션 효과가 동작하기 위해서는 먼저 animation-name 속성을 이용하여 요소와 키 프레임을 연결해 주어야 합니다.  <출처 : http://tcpschool.com/css/css3_transform_animation

보통은 from 키워드에서 처음 스타일을 명시하고, to 키워드서 마지막 스타일을 명시한다.

하지만 좀 더 복잡한 애니메이션 효과를 나타내기 위해서는 from 키워드나 to 키워드 대신에 퍼센트(%)를 사용해야 한다

0%에는 처음 스타일을, 100%에는 마지막 스타일을 명시하고, 중간에 원하는 수만큼의 키 프레임을 생성할 수 있습니다

뭐 의미는 비슷하다. 로딩 창에서 시작이 0%이고 완료되면 100% 이런 느낌으로 받아들이자.

animation:rotate15s linearinfinite을 이해해 보자

animation을 이용하여 속성을 부여하는 것이다. rotate 15s 란 애니메이션이 한번 도는데 걸리는 시간을 몇 초로 설정하는 시간을 주는 것이다. 1s 설정하면 1초에 한바뀌식 돈다. (이거로 나중에 태양계(solar system) 구현하면 재밌을 듯)

linear 이외에도 ease | ease-in | ease-out | ease-in-out | cubic-bezier  있다. 도는 스타일 설정이다. 그냥 선의 속도로 회전할 수 있게 linear로 설정해 주었다. 그리고 무한이 라는 infinite로 속성 값을 주었다.

<출처 : https://webdesign.tutsplus.com/ko/tutorials/a-beginners-introduction-to-css-animation--cms-21068>

transform-style:preserve-3d; 을 이해해 보자

transform-style의 기본 값은 "flat"로, 자식 요소는 2D의 2차원에서 부모 요소와 동일한 평면에 배치되지만, "transform-style : preserve-3d;"을 지정하여 3D 공간에 배치되도록 한다; 이렇게 함으로써 3D 느낌을 낼 수 있다.

마진(margin) 은 border  여백을 설정하는 건데  여기서는 margin-top  120px 주어 border 위 여백에 120px 만큼 공간을 주었다.

 

 

다음으로는 이미지의 width와 height를 통일시켜주겠습니다.

이미지(img)들이 현재 single-rb  클래스 안에 있으므로 

1
2
3
4
5
.single-rb img {
    height : 400px;
    width : 400px;
}
 
cs

이렇게 해주면 sigle-rb 클래스 안에 존재하는 모든 img 파일 들의 width와 height를 400px로 만들 수 있습니다.

.single-rb  class

이제 사진들의 위치를 어디에 위치시켜야 할지 결정해야 한다.

여기서 사용하는 속성은 position이다.

 

1. 정적 위치(static position) 지정 방식

HTML 요소의 위치를 결정하는 가장 기본적인 방식은 정적 위치(static position) 지정 방식입니다.

position 속성 값이 static으로 설정된 요소는 top, right, bottom, left 속성 값에 영향을 받지 않습니다.

정적 위치(static position) 지정 방식은 단순히 웹 페이지의 흐름에 따라 차례대로 요소들을 위치시키는 방식입니다.

 

2. 상대 위치(relative position) 지정 방식

상대 위치(relative position) 지정 방식은 해당 HTML 요소의 기본 위치를 기준으로 위치를 설정하는 방식입니다.

HTML 요소의 기본 위치란 해당 요소가 정적 위치(static position) 지정 방식일 때 결정되는 위치를 의미합니다.

 

3. 고정 위치(fixed position) 지정 방식

고정 위치(fixed position) 지정 방식은 뷰포트(viewport)를 기준으로 위치를 설정하는 방식입니다. 

즉, 웹 페이지가 스크롤되어도 고정 위치로 지정된 요소는 항상 같은 곳에 위치하게 됩니다.

 

4. 절대 위치(absolute position) 지정 방식

절대 위치(absolute position) 지정 방식은 고정 위치가 뷰포트를 기준으로 위치를 결정하는 것과 비슷하게 동작합니다.

단지 뷰포트(viewport)를 기준으로 하는 것이 아닌 위치가 설정된 조상(ancestor) 요소를 기준으로 위치를 설정하게 됩니다.

하지만 위치가 설정된 조상(ancestor) 요소를 가지지 않는다면, HTML 문서의 body 요소를 기준으로 위치를 설정하게 됩니다.

 

이미지들이 top, right, bottom, left 속성 값에 영향을 받으므로 static 속성은 탈락.

이미지들이 각각 상대적인 위치에 존재 하지만 어떤 공간을 중심으로 하여 형성해야 하므로 relative 속성도 탈락.

fixed 또는 absolute를 쓰겠다. 솔직히 말해서 아직 초보적인 단계여서 차이점을 잘 모르겠다... 아직까지는 똑같아서...

그 공간의 크기를  400px로 height witdth로 설정하겠다. 큐브가 돌아갈 위치를 잡아주는 것이다.

1
2
3
4
5
.single-rb div{
        position: absolute;
        width : 400px;
        height : 400px;
}
cs

 

이제 모든 사진들의 크기를 통일시켜주었습니다. 이제 사진들을 좌측 , 우측, 앞 , 뒤에 배치하는 작업을 해보겠습니다.

 

 변형에 앞서 공부해야 할 내용들이 몇 가지 존재한다.

CSS3 3D transform 메서드  < TCPschool에서 설명해주고 있는 transform의 속성들이다.

matrix3d(n×16) 4x4 행렬을 이용한 16개의 매개변수로 모든 3D 변형 메소드를 한 번에 설정함.
rotate3d(x,y,z,angle) 해당 요소를 주어진 각도만큼 x축, y축과 z축을 기준으로 회전시킴.
rotateX(angle) 해당 요소를 주어진 각도만큼 x축을 기준으로 회전시킴.
rotateY(angle) 해당 요소를 주어진 각도만큼 y축을 기준으로 회전시킴.
rotateZ(angle) 해당 요소를 주어진 각도만큼 z축을 기준으로 회전시킴.
translate3d(x,y,z) 현재의 위치에서 해당 요소를 주어진 x축, y축과 z축의 거리만큼 이동시킴.
translateX(x) 현재의 위치에서 해당 요소를 주어진 x축의 거리만큼 이동시킴.
translateY(y) 현재의 위치에서 해당 요소를 주어진 y축의 거리만큼 이동시킴.
translateZ(z) 현재의 위치에서 해당 요소를 주어진 z축의 거리만큼 이동시킴.
scale3d(x,y,z) 해당 요소의 크기를 주어진 배율만큼 x축, y축과 z축 방향으로 늘리거나 줄임.
scaleX(x) 해당 요소의 x축 크기를 주어진 배율만큼 늘리거나 줄임.
scaleY(y) 해당 요소의 y축 크기를 주어진 배율만큼 늘리거나 줄임.
scaleZ(z) 해당 요소의 z축 크기를 주어진 배율만큼 늘리거나 줄임.
perspective(n) 3D 요소에 원근감을 표현할 때 사용할 픽셀 수를 설정함.

 

CSS3 3D transform 속성

속성설명
transform 요소에 2D 또는 3D 변형(transform)을 적용함.
transform-origin 요소에 변형(transform)을 적용하는 변환 중심을 설정함.
transform-style 요소에 변형을 적용할 때 그 변환이 자식(child) 요소들에게도 적용될지 안 될지를 설정함.
perspective 3D 요소에 원근감을 표현할 때 사용할 픽셀 수를 설정함.
perspective-origin 3D 요소에 원근감을 표현할 때 사용할 기준 축을 설정함.
backface-visibility 요소의 앞면만을 표현하고, 뒷면을 표현할지 안 할지를 설정함.

출처: http://tcpschool.com/css/css3_transform_3Dtransform

 

1
2
3
.front-side{
    transform: translateZ(400px);
}
s

 

 

해석을 하면 front-side에 있는 사진을 현재 위치에서 해당 요소를 주어진 Z축방향으로 400px  만큼 이동시키게 됩니다. 

아무 변화도 일어나지 않은 거 같지만 사진이 앞으로 400px 만큼 전진해있는 상태이다 

상황을 좌측이나 우측에서 보면 아래와 같이 사진이 이동해있는 상태이다.

다음에는 rear 쪽을 만들어보자

기존의 사진이 뒤쪽에 가서도 현재와 똑같이 보이게하려면 사진을 좌위 반전 시켜주어야한다.  
 
우리가 거울을 볼때 오른쪽 손을 올리면  왼손을 올리는것처럼 보이는 효과를 없애주기 위해서
transform : rotateY(180deg) 를 해주었다 . 180도회전해주었다는의미이다.
 
만약  실수로 transform : rotateX(180deg) 를 해준다면 상하반전이 되기 때문에 이상해진다.
 
쉽게 그냥 좌표평면 상에서  x축대칭 y칭대칭 이런 느낌만 느껴지면 충분히 이해가 된것이다. 
 
 
 
 
입체감을 살려주기 위해서 back-side 이미지도 Z축 방향으로 200px 만큼 전진 시켜주었다.
 
1
2
3
4
.back-side{
    transform: rotateY(180deg);
    translateZ(200px);
}
s

 

이제 left-side를 만들어주자.

1
2
3
4
5
.left-side{
    transform: rotateY(-90deg);
    translateZ(-200px);
    transform-origin: left;
}
cs

제일 아랫줄에 있는 transform 속성 transform-origin 은 요소에 변형(transform)을 적용하는 변환 중심을 설정해준다.

즉 왼쪽 입장에서 원하는 방향으로 축을 옮길 수도 있다. 정육면체 느낌을 살릴 수 있도록 뒤로 translateZ(-200px)로 해주었다. 그러지않은면 이상한 모양이 형성된다. 함몰된 육면체.... 그래서 200px 만큼 이동시켜주어야 한다. 

그리고 y축을 기준으로 -90도 회전해주어야 한다. rotateY(0) 일 때는   back-side에 있는 사진 뒤에 바로 붙어 있게 되고 

rotateY(90 deg)로 설정하면 큐브가 열리게 된다. 음의 방향으로 큐브를 닫아주기 위해서는 rotateY(-90 deg)로 해주어야 한다.  공간에서 일어나고 있는 일이랑 조금 헷갈리수도 있지만 충분히 이해할 수 있는 내용이니 포기하지 말자!

 

다음으로 right-side이다.

1
2
3
4
5
.right-side{
    transform: rotateY(90deg);
    translateZ(200px);
    transform-origin: right;
}
cs

정확히 left-side와 대칭되는 내용이다.  내용 동일.

현재까지의 작업 결과 사진들은 생각했던 대로 잘 배치되었다. (front-side가 나오기 전에 얼른 캡처했습니다. front 나오면 뒤가 가려집니다.)

이제 남은 건 top과 bottom이다 이번 프로젝트에서는 단순히 rotate 시키는 게 목적이므로 아쉽게도 top과 bottom 은 화면상에 공개되지 않는다..ㅠㅠ 나중에 위아래 다 보이도록 만들어보겠다.!!

1
2
3
4
5
6
7
8
9
10
.top-side{
    transform: rotateX(-90deg);
    translateZ(-200px);
    transform-origin: top;
}
.bottom-side{
    transform: rotateX(90deg);
    translateZ(200px);
    transform-origin: bottom;
}
cs

단순하게 위아래 뚜껑 닫아주는 역할이다 사진은 따로 html에서부터 추가하지 않았다. 어차피 보이지 않기 때문에 ^^ 

위 설명했던 거 흐름 따라왔으면 왜 rotateX로 +/- 90 인지 이해가 될 것입니다.

이제 애니메이션 속성인  @keyframes animation을 사용해주면 됩니다.

 
1
2
3
4
5
6
7
8
9
@keyframes rotate{
 
  0%{transform: rotateY(0);}
 
  100%{transform: rotateY(-360deg);}
 
}
 
 
 
cs
 

반시계 방향으로 회전시킬 수도 있고 시계방향으로 회전시킬 수 있다. 나는 시계방향으로 회전시켜보겠다.

만약 반시계 방향을 원한다면 +360 deg로 값을 주면 된다.

이것으로  큐브가 완성이 되었습니다.!

CSS 풀 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.rotating-box{
    width : 400px;
    height : 400px;
    margin: 10px auto;
    perspective: 800px;
}
.single-rb{
    width: 400px;
    animation: rotate 6s linear infinite;
    transform-style:preserve-3d;
    margin-top: 120px; 
}
 
.single-rb img {
    height : 400px;
    width : 400px;
}
.single-rb div{
        position: absolute;
        width : 400px;
        height : 400px;
}
 
.front-side{
    transform: translateZ(400px);
}
.back-side{
    transform: rotateY(180deg);
    translateZ(200px);
}
.left-side{
    transform: rotateY(-90deg);
    translateZ(-200px);
    transform-origin: left;
}
.right-side{
    transform: rotateY(90deg);
    translateZ(200px);
    transform-origin: right;
}
.top-side{
    transform: rotateX(-90deg);
    translateZ(-200px);
    transform-origin: top;
}
.bottom-side{
    transform: rotateX(90deg);
    translateZ(200px);
    transform-origin: bottom;
}
 
@keyframes rotate{
    0%{transform:  rotateY(0);}
    100%{transform: rotateY(-360deg);}
}
 
cs

 

 

 

 

 

https://make3DANimation--kind.repl.co

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함