0. 들어가기
토스 어시스턴트 면접 이후에 애니메이션과 같은 좀더 역동적인 효과들을 공부해봐야겠다고 생각했다.
이전에 구름 1기 당시에 결제했던 웹 애니메이션 API 강의를 들으면서 새로 알게 된 것들을 정리해봤다.
1. transition
transition은 CSS와 JS에서 요소의 상태 변화에 애니메이션 효과를 추가하는 방법이다.
웹 개발에서는 주로 부드러운 인터페이스나 UI의 상태 변화를 주기 위해 사용된다.
transition: property duration [delay] [timing-function];
transition에는 CSS 속성과 지속 시간, 속도 곡선, 지연 시간 4가지가 있다.
CSS 속성과 지속 시간은 필수지만 나머지 2개는 선택이다.
.box {
width: 100px;
height: 100px;
background: coral;
transition: transform 1s 1s, background 2s 1s linear;
}
.box-action {
transform: translateX(300px);
background: blue;
}
위 코드는 box에 hover할 때 1초 지연 후 1초동안 X축으로 300px 이동하고,
coral 배경색이 1초 지연 후 2초동안 천천히 blue로 변경된다.
속도 곡선(timing-function)은 애니메이션의 속도를 제어하는 속성으로 ease가 디폴트다.
- ease: 천천히 시작 - 빠르게 중간 - 천천히 마지막
- linear: 시작 - 끝이 일정한 속도
- ease-in: 천천히 시작 - 점점 빨라짐
- ease-out: 빠르게 시작 - 점점 느려짐
- ease-in-out: 천천히 시작 - 빠르게 중간 - 천천히 마지막 (ease와 유사)
개발자 모드에서 임의로 조정한 후에 그대로 사용할 수도 있다.
또한 주의해야 할 점이 수로 표현될 수 있는 속성들만이 transition에 사용될 수 있다.
예를 들어 display: block -> display: none으로 변경 시키려는 건 불가능하다. (대신에 opacity 조절)
transition은 CSS 속성이 변할 때 그 변화를 부드럽게 만들어주는 역할을 한다.
따라서 transition을 적용할 수 있는 속성들은 레이아웃의 변화에 대한 어떤 변화를 서서히 표현할 수 있어야 한다.
즉 중간 단계에서 변화하는 과정이 보여져야 하는데 block에서 none이 되는 건 표현할 수가 없기 때문이다.
2. transition event
transition에도 이벤트가 있다.
- transitionstart: transition이 실제로 시작될 때
- 어떤 스타일이 변화하기 시작할 때 시작된다. 위 코드를 예시로 들면 coral -> blue로 변할 때
- transitionend: transition이 끝날 때
- transitionrun: transition이 동작할 때
- 어떤 속성이 전환되고 있다는 신호. 여러 번 발생할 수 있다.
- transitioncancel: transition이 취소될 때
- 특정 요소가 remove되는 경우
Playground | MDN
The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.
developer.mozilla.org
MDN playground에서 직접 transition을 확인해보면 이해가 더 잘 된다.
3. svg에 transition 적용하기
svg는 대표적인 벡터 기반의 이미지로, 아이콘이나 일러스트들을 표현할 때 사용되는 확장자다.
png(픽셀 기반)와 다르게 점과 점 사이의 연산에 의해 그려지기에 사이즈가 아무리 커져도 화질이 깨지지 않는다.
svg 파일을 VSC에서 열어보면 이게 무슨 소리지 이해할 수 없는 코드들이 잔뜩 있는데,
사실 가만히 들여다 보면 <path>, <circle>, <rect> 같은 태그들을 확인할 수 있다.
선, 원, 사각형 등을 나타내고 있어서 svg 이미지에서 특정 요소를 찾아야 하면 그 부분들을 확인해보면 된다.
강의에서는 자동차 키의 '동그란' 부분을 누르면 날이 180도 돌아가도록 애니메이션을 구현하려고 한다.
<g>
<path class="key-blade cls-3" d="M223.23,20.53h-22.68c-6.26,0-11.34,5.08-11.34,11.34V213.28s45.35,0,45.35,0V31.87c0-6.26-5.08-11.34-11.34-11.34Z"/>
<path class="cls-2" d="M349.01,167.61H218.22c-30.28,0-54.82,24.54-54.82,54.82v220.05c0,11.27,9.13,20.4,20.4,20.4h130.8c30.28,0,54.82-24.54,54.82-54.82V188.02c0-11.27-9.13-20.4-20.4-20.4Z"/>
<circle class="key-btn cls-1" cx="211.89" cy="213.45" r="22.68"/>
</g>
보다시피 여기의 circle이 그 '동그란' 부분에 해당 될 것이다.
그래서 해당 부분에 class를 주고 여길 click했을 때 어떤 classList의 toggle을 적용해두면 된다.
그런데 만약 svg 파일이 img 태그로 표현되어 있다면 그게 불가능하기 때문에 object 태그를 사용한다.
object 태그는 HTML에서 외부 리소스를 삽입할 때 사용하는 요소로, 로드 뿐만 아니라 상호작용도 가능케 한다.
<!-- <img src="images/key.svg" alt="key" class="key" /> -->
<object data="images/key.svg" class="key" type="image/svg+xml"></object>
이런 식으로 data와 type을 적어주면 된다.
또한 기본적으로 html 객체의 transform-origin은 왼쪽 상단이기 때문에 이 기준점을 정해줘야 한다.
.key-blade {
transform: rotate(-180deg);
transform-origin: 211.89px 213.45px;
transition: 0.3s;
}
이런 식으로 차 키의 날이 동그란 부분(211.89px 213.45px)을 기준으로 -180도 회전할 수 있게 한다.
특정 엘리먼트의 크기와 뷰포트에서 상대적인 위치를 찾고 싶다면 Element.getBouncingClientRect()를 사용할 수도 있다.
내가 찾고 있는 엘리먼트의 위치는 x축(왼쪽)으로 400, y축(위쪽)으로 90에 위치하며 너비 133px, 높이 223px이다.
hand.addEventListener('click', () => {
if (isKeyInHand) {
key.style.transform = 'scale(1) translate(0, 0)';
} else {
const handRect = hand.getBoundingClientRect();
console.log(handRect);
const leftPosition = handRect.left + 150;
const topPosition = handRect.top - 60;
key.style.transform = `scale(0.5) translate(${leftPosition}px, ${topPosition}px)`;
}
});
key.addEventListener('transitionend', () => {
isKeyInHand = !isKeyInHand;
});
이런식으로 isKeyInHand이라는 불리언 값에 따라 스타일링을 줄 수 있다.
만약 손에 열쇠가 들어오면 크기를 1, translate를 0, 0으로 바꾸고, 그렇지 않다면 손에서 왼쪽으로 150px, 위에서 60px 떨어진 곳에 위치시킴과 동시에 크기를 0.5로 줄여준다.
그리고 transition이 다 끝나면 다시 transition을 주기 위해 불리언 값을 부정해주면 된다.
웹 애니메이션의 새로운 표준, Web Animations API 강의 | 1분코딩 - 인프런
1분코딩 | 라이브러리는 선택이지만, 웹 표준 기술은 필수입니다. 웹 애니메이션의 새로운 표준인 Web Animation API에 남들보다 빠르게 적응하고, 실무에도 바로 활용해보세요!, [임베딩 영상] 두고
www.inflearn.com
'👋🏻 JavaScript' 카테고리의 다른 글
[JavaScript] Package Manager (npm, yarn, pnpm) 이해하기 (1) | 2024.06.22 |
---|---|
[JavaScript] 클래스 (1) | 2023.12.21 |
[JS] json-server로 만드는 프론트엔드 연습용 가짜 서버 (0) | 2023.08.02 |