#
9.transform
In
#
목차
1. 개요 2. 기본문법 2.1. 2D 2.2. 3D 2.2.1. perspective 2.2.2. perspective-origin
3. 응용예제 3.1. 다양한 transform 3.2. 예제: 회전하는 코알라 3.2.1. 예제: 카드뒤집기
3.3. 예제 hover시 커지는 이미지 3.4. 마우스위치에 대응하는 애니메이션 3.5. 3차원 공간에서 회전하는 이미지 3.5.1. css 버전 3.5.2. js 버전
3.6. 추가예제
#
1. 개요
CSS의 transform 속성은 요소의 2D 또는 3D 변환을 적용합니다. 이 변환은 요소의 크기, 위치, 회전 등을 변경할 수 있습니다.
#
2. 기본문법
#
2.1. 2D
#
2.2. 3D
#
2.2.1. perspective
Perspective 값이 크면 멀어서 작게, 작으면 가까워서 크게보임. (값은 0보다 커야함)
사람의 시지각은 멀리 떨어진 사물은 작게, 가까이 있는 사물은 크게 보인다.
#
2.2.2. perspective-origin
사용자의 시선 위치를 조정하여 소실점적용
#
3. 응용예제
#
3.1. 다양한 transform
html
<div class="transform_container">
<div class="origin">
<div class="rotatex"></div>
</div>
<div class="origin">
<div class="rotatey"></div>
</div>
<div class="origin">
<div class="rotatez"></div>
</div>
<div class="origin">
<div class="rotatexyz"></div>
</div>
</div>
#
시작
css
.transform_container {
width: 800px;
margin: 20px auto;
}
.origin {
width: 100px;
height: 100px;
margin: 40px;
border: 1px solid black;
display: inline-block;
}
.origin > div {
width: 100px;
height: 100px;
background-color: orange;
transition: all 3s; /* 3초 동안 회전하도록 트랜지션 적용 */
}
#
STEP1
.rotatex:hover {
transform: rotateX(55deg); /* x축으로 55도 회전 */
}
.rotatey:hover {
transform: rotateY(55deg); /* y축으로 55도 회전 */
}
.rotatez:hover {
transform: rotateZ(55deg); /* z축으로 55도 회전 */
}
.rotatexyz:hover {
transform: rotate3d(0, 1.2, -1.5, 55deg); /* x,y,z축으로 55도 회전 */
}
#
3.2. 예제: 회전하는 코알라
backface
html
<div class="transform_container">
<img src="http://qwerew.cafe24.com/images/koala1.png" alt="icon" />
</div>
.transform_container {
width: 200px;
margin: 30px auto;
}
img {
width: 100%;
border: 1px solid #ccc;
border-radius: 50%;
box-shadow: 5px 5px 63px 2px #00000040;
animation: rotateAnimal 2.5s infinite alternate; /* rotateAnimal 애니메이션 2.5초 동안 실행. 무한 반복 */
animation-play-state: paused;
animation-fill-mode: forwards;
}
img:hover {
animation-play-state: running;
}
@keyframes rotateAnimal {
from {
transform: perspective(200px) rotateY(0deg);
}
50% {
transform: perspective(200px) rotateY(-180deg);
}
to {
transform: perspective(200px) rotateY(-360deg);
}
}
#
transform: perspective(200px)
VS perspective:200px
둘다 3D 공간의 z축 깊이를 설정한다
- 문법이 다르다
transform: perspective(200px)
: transform 속성에 값으로 작성하는 방식 다른 transform 속성과 함께 사용시 띄어쓰기로 구분하여 작성해야 한다.perspective:200px
: perspective 속성에 값을 작성하는 방식
- 선언 대상이 다르다
transform: perspective(200px)
: 원근감을 적용할 요소에 직접 작성perspective:200px
: 원근감을 적용할 요소의 부모요소에 작성
#
3.2.1. 예제: 카드뒤집기
html
<div class="card">
<div class="front"><span>A♥</span> ♥ <span>A♥</span></div>
<div class="back">뒤집어🐨</div>
</div>
css
body {
font-size: 200%;
margin: 100px;
color: #eee;
background-color: #fafafa;
}
div.card {
width: 176px;
height: 246px;
margin: 0 auto;
cursor: pointer;
}
div.card div {
position: absolute;
width: 160px;
height: 230px;
font-size: 2em;
text-align: center;
line-height: 230px;
color: #c00;
background-color: #fff;
border-radius: 5px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5), 2px 2px 35px rgba(0, 0, 0, 0.1);
transition: all 1s ease;
}
div.card div span {
position: absolute;
left: 0;
top: 0;
font-size: 0.5em;
width: auto;
line-height: 1em;
}
div.card div span:last-child {
left: auto;
top: auto;
right: 0;
bottom: 0;
transform: rotate(180deg);
}
div.card div.back {
font-size: 0.8em;
color: #fff;
background: #36c;
}
div.card {
perspective: 400px;
}
div.card div {
backface-visibility: visible;
backface-visibility: hidden;
}
div.card div.back {
transform: rotateY(0deg);
}
div.card div.front {
transform: rotateY(-180deg);
}
div.card:hover div.back {
transform: rotateY(-180deg);
}
div.card:hover div.front {
transform: rotateY(0deg);
}
backface-visibility
- 요소의 뒷쪽에서 앞면이 보이게 할지 정하는 속성- 값:
visible | hidden | initial | inherit
#
3.3. 예제 hover시 커지는 이미지
html
<div class="transform_container">
<img src="https://qwerew.cafe24.com/images/1.jpg" />
<span> 트랜스폼 알아보기 </span>
</div>
#
시작
css
div.transform_container {
width: 50%;
margin: 200px auto;
}
div.transform_container img {
transition: all 0.35s;
width: 100%;
}
#
STEP1 [transform3D적용]
div.transform_container:hover img {
div.transform_container {
perspective: 1000px;
border: 1px solid;
}
transform: translate3D(100px, 100px, 200px);
}
#
STEP2 [perspective-origin]
div.transform_container {
perspective: 500px;
perspective-origin: 50% 50%;
}
div.transform_container:hover img {
transform: translate3D(0px, 0px, 200px);
}
#
STEP3 [scale]
translateZ
와 함께 사용
div {
perspective-origin: 0px 10px;
}
div img {
transform: scaleZ(1);
}
div:hover img {
transform: translateZ(200px) scaleZ(5);
}
#
3.4. 마우스위치에 대응하는 애니메이션
html
<div id="top">
<div class="perspective">
<div class="card">
<div class="thumb"></div>
<h2>코알라 만져보고 싶어요</h2>
<span>코알라 너무 좋아</span>
</div>
</div>
</div>
css
@import url(https://qwerewqwerew.github.io/source/style/reset.css);
body {
background: linear-gradient(to right, #ffffff, #f8dce2);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
font-family: 'Pretendard';
}
.perspective {
width: 100%;
perspective: 1000px;
}
#top {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin: auto;
}
.card {
width: 270px;
height: 413px;
margin: auto;
box-shadow: 0 70px 63px -60px #494848;
transform-style: preserve-3d;
transition: transform 0.05s linear;
}
.card .thumb {
background: #e99fb6 url(https://qwerew.cafe24.com/images/koala1.png) center center;
background-size: 150px;
height: 100%;
width: 100%;
border-radius: 15px;
}
.card .thumb:after {
background: inherit;
content: '';
display: block;
position: absolute;
left: -60px;
top: 40px;
width: 100%;
height: 108%;
z-index: -1;
filter: blur(55px);
}
.card h2 {
position: absolute;
top: 0;
left: -60px;
font-size: 40px;
font-weight: 900;
color: transparent;
transform: translateZ(80px);
background: linear-gradient(to right, #e98b89, #547fc0);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.card span {
position: absolute;
bottom: 40px;
right: -280px;
font-size: 37px;
font-weight: 600;
transform: translateZ(35px);
}
img {
margin: auto;
display: block;
border-radius: 15px;
}
javascript
var o = $('.card');
var o2 = $('h2');
$('#top').on('mousemove', function (t) {
console.log(t);
var e = -($(window).innerWidth() / 2 - t.pageX) / 30,
n = ($(window).innerHeight() / 2 - t.pageY) / 10;
o.attr('style', `transform: rotateY(${e}deg) rotateX(${n}deg)`);
o2.attr({ style: `transform: rotateY(${e * 0.5}deg) rotateX(${n}deg) translateZ(20px) translateX(${n * 1.5}px)` });
});
#
3.5. 3차원 공간에서 회전하는 이미지
#
3.5.1. css 버전
가로, 세로 200픽셀인 8장의 사진을 이용해 Y축을 기준으로 회전하 는 애니메이션을 제작하고 클릭하면 멈추도록 효과 적용
스타일에 변수를 이용해 순서대로 숫자로 지정 html 에 작성한 변수는 아래처럼 동작한다
<!-- .box>(span>img)*8 -->
<div class="box">
<span style="--i: 1"><img src="./imgs/1.jpg" alt="" /> </span> <span style="--i: 2"><img src="./imgs/2.jpg" alt="" /> </span> <span style="--i: 3"><img src="./imgs/3.jpg" alt="" /></span> <span style="--i: 4"><img src="./imgs/4.jpg" alt="" /></span> <span style="--i: 5"><img src="./imgs/5.jpg" alt="" /></span> <span style="--i: 6"><img src="./imgs/6.jpg" alt="" /></span> <span style="--i: 7"><img src="./imgs/7.jpg" alt="" /></span> <span style="--i: 8"><img src="./imgs/8.jpg" alt="" /></span>
</div>
"body"를 플렉스로 지정하고 배경은 방사형그레디언트를 적용한 후 스크롤했을 때 고정되도록 “background-attachment" 속성 값 을 “fixed"로 지정한다.
transform-style
: 3차원 공간에서 요소(element)의 공간에 표시 또는 평면적으로 표시 할지 결정한다.
transform-style: flat;
평면으로 표시transform-style: preserve-3d;
공간으로 표시8개의 이미지는
span
태그에 인라인스타일 속성값으로 커스텀스타일을 적용 하고 값은 "1"부터 "8"까지의 숫자로 정의되어 있으므로img1
은 Y축으로 45 도 회전하고 Z축으로 400픽셀이동되어 표시되면 입체적으로 보여진다.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
height: 2000px;
background: radial-gradient(#2c5364, #0f2027);
background-attachment: fixed;
}
.box {
position: relative;
top: 30vh;
width: 200px;
height: 200px;
transform-style: preserve-3d;
animation: animate 20s linear infinite;
}
@keyframes animate {
0% {
transform: perspective(1000px) rotateY(0deg);
}
100% {
transform: perspective(1000px) rotateY(360deg);
}
}
.box span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center;
transform-style: preserve-3d;
transform: rotateY(calc(var(--i) * 45deg)) translateZ(400px);
-webkit-box-reflect: below 0px linear-gradient(transparent, transparent, #0009);
}
.box span img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.item {
position: fixed;
left: 0;
width: 300px;
height: 300px;
background-color: #fff;
}
#
3.5.2. js 버전
<div class="box">
<span><img src="./imgs/1.jpg" alt="" /></span><span><img src="./imgs/2.jpg" alt="" /></span><span><img src="./imgs/3.jpg" alt="" /></span><span><img src="./imgs/4.jpg" alt="" /></span><span><img src="./imgs/5.jpg" alt="" /></span><span><img src="./imgs/6.jpg" alt="" /></span><span><img src="./imgs/7.jpg" alt="" /></span><span><img src="./imgs/8.jpg" alt="" /></span>
</div>
<script src="1.js"></script>
const span = document.querySelectorAll('span');
span.forEach((el, idx) => {
el.setAttribute('style', `--i:${idx - 1}`);
});