Types of animation
- Transition : 한 페이지에서 다른 페이지로 이동
- 모달 열기 또는 닫기, 다음 단계로 이동하는 다단계 마법사와 같이 페이지의 내용을 상당히 변경합니다.
- Supplements : "위치" 또는 작업을 변경하지 않고 페이지에서 정보를 추가하거나 제거합니다.
- 예를 들어 알림이 모서리에 나타날 수 있습니다.
- Feedback : 사용자가 애플리케이션이 사용자 입력에 어떻게 응답했는지 이해하는 데 도움이 됩니다.
- 예를 들어, 양식을 제출할 때 나타나는 오류 메시지 또는 클릭 시 아래로 미끄러지는 버튼이 눌러져 있음을 나타냅니다.
- Demonstration : 사용자에게 작동 방식을 보여주는 교육용으로 사용됩니다.
- "마친 겹침 규칙" 강의의 시각화와 같은 예시입니다.
- Decoration은 미적이며 페이지의 정보에 영향을 미치지 않습니다.
- 예를 들어 사용자에게 전달되는 좋은 소식을 축하하기 위한 색종이 조각입니다.
우리가 추가하는 모든 애니메이션에는 목적이 있어야 합니다.
우리는 단지 화려하기 위해 애니메이션을 추가해서는 안됩니다.
애니메이션은 제품을 더 세련된 느낌으로 만들 수 있지만, 사용자에게 애니메이션의 존재 이유가 명확할 때만 가능합니다.
현실주의
자연 세계의 사물은 순간이동 하지 않습니다.
애니메이션이 사물이 현실에서 움직이는 방식을 시뮬레이션하여
제품을 더 "현실적으로" 느끼게 만들 수 있습니다.
저는 "현실주의" 애니메이션이 #3, 피드백의 하위 집합이라고 말하고 싶습니다.
클릭, 호버링, 스크롤 등 애플리케이션이 입력에 응답하는 방식을 사용자에게 보여줍니다.
애니메이션 지속시간
적응형 애니메이션
게임 초기 로딩 시 컷신을 보여주고,
그 이후에 컷신이 재생될 필요가 있으면, 스킵 버튼을 보여주는 방식을 적용할 수 있습니다.
액션 주도 애니메이션
-
Enter duration: 500ms
-
Enter timing function: ease-out
-
Exit duration: 250ms
-
Exit timing function: ease-in
예제 1 : 호버 시 커지는 버튼
버튼이 작아지고 커지는, 피드백 타입 애니메이션은 모달과 같이 차단 전환 프로세스가 아니므로,
미묘하게 작아지는 것처럼 작아지는 시간을 느리게 할 수 있습니다.
<style>
.button {
/* Exit animations */
transition: transform 500ms;
}
.button:hover {
transform: scale(1.1);
/* Enter animation */
transition: transform 200ms;
}
.button {
width: 200px;
height: 50px;
border-radius: 6px;
border: 2px solid;
will-change: transform;
}
</style>
<button class="button">
Hello World
</button>
예제 2 : 모달
사용자 인터랙션 기반 상태를 이용해야 하므로, js가 필요합니다.
const ENTER_DURATION = '500ms';
const EXIT_DURATION = '250ms';
const ENTER_EASE = 'ease-out';
const EXIT_EASE = 'ease-in';
function Modal({ isOpen, children }) {
return (
<Wrapper
style={{
'--transition-duration': isOpen
? ENTER_DURATION
: EXIT_DURATION,
'--timing-function': isOpen
? ENTER_EASE
: EXIT_EASE,
}}
>
<DialogContent>
{children}
</DialogContent>
</Wrapper>
)
}
const Wrapper = styled(DialogOverlay)`
transition:
transform var(--transition-duration) var(--timing-function);
`;
전체 코드 및 동작하는 예제 보기
https://courses.joshwcomeau.com/playground/modal-transitions
예제 : Pushable Button
보통 버튼은 보더나 그림자를 이용하지만, transition을 통해 더 부드러운 효과를 얻을 수 있습니다.
위 버튼은 세 가지 효과를 갖습니다.
-
Hovering
-
Clicking
-
Leaving (moving the mouse away from the button)
테스트 해보기
<style>
.front {
transform: translateY(-4px);
transition: transform 500ms;
}
.pushable:hover .front {
transform: translateY(-6px);
transition: transform 250ms;
}
.pushable:active .front {
transform: translateY(-2px);
transition: transform 50ms;
}
.pushable {
background: hsl(340deg 100% 40%);
border: none;
border-radius: 12px;
padding: 0;
cursor: pointer;
}
.front {
display: block;
padding: 12px 42px;
border-radius: 12px;
font-size: 1.25rem;
background: hsl(345deg 100% 70%);
color: white;
}
</style>
<button class="pushable">
<span class="front">
Push me
</span>
</button>
위 솔루션을 리액트를 활용하여 액션 기반 애니메이션으로 리팩토링 할 수 있습니다.
function Button({ children }) {
/*
We track 4 actions:
• "hovering", the user is mousing over the button
• "depressed", the user is pressing down on it
• "released", the user has released the button
• "exited", the user has moused away
*/
const [
mostRecentAction,
setMostRecentAction
] = React.useState(null);
/* Calculate the right styles based on the action */
let styles = {};
if (mostRecentAction === 'hovering') {
styles = {
transform: 'translateY(-6px)',
transition: 'transform 250ms',
}
} else if (mostRecentAction === 'depressed') {
styles = {
transform: 'translateY(-2px)',
transition: 'transform 50ms',
}
} else if (mostRecentAction === 'released') {
styles = {
transform: 'translateY(-6px)',
transition: 'transform 200ms',
}
} else {
// The default value
// Used initially, before any actions have occurred, and also
// when exiting.
styles = {
transform: 'translateY(-4px)',
transition: 'transform 500ms',
}
}
return (
<button
style={styles}
// Set the action based on the JS event:
onMouseEnter={() => setMostRecentAction('hovering')}
onMouseDown={() => setMostRecentAction('depressed')}
onMouseUp={() => setMostRecentAction('released')}
onMouseLeave={() => setMostRecentAction('exited')}
>
{children}
</button>
);
}
애니메이션 오케스트레이션
애니메이션의 순서는 생각보다 중요합니다.
한번에 모든 전환이 시작되는 것보다 더 자연스러운 애니메이션을 만들 수 있습니다.
- 배경은 즉시 페이드 인되기 시작하여 오랜 시간(1000ms) 지속됩니다.
- 모달은 250ms 동안 기다린 다음 400ms 이상 미끄러집니다.
- 닫기 버튼은 이제 기본적으로 숨겨져 있으며 고유한 전환이 제공됩니다. 600ms 후에 애니메이션을 시작하고 250ms 동안 지속됩니다.
위 예제 보기 : https://courses.joshwcomeau.com/playground/modal-orchestrations
이런 효과를 가장 잘쓰는 회사는 바로 apple.com 입니다.
위 홈페이지에서 검색 버튼을 눌러보면 다음과 같은 효과를 경험할 수 있습니다.
- 배경이 페이드 인
- 헤더 네비게이션이 페이드 아웃
- 드롭다운이 페이드 인
- 드롭다운이 표시되면 드롭다운 항목이 나타납니다
- 드롭다운 위의 검색 인풋과 및 닫기 버튼이 슬라이드 인
transitionEnd 이벤트
한 애니메이션 종료 시 다른 애니메이션 트리거
element.addEventListener('onTransitionEnd', () => {
// Whenever a transition completes on the target element,
// this function will be called.
});
참고 자료
Improving the Payment Experience With Animations
“Building a Magical 3D Button”
Meaningful Motion with Action-Driven Animation
'FrontEnd' 카테고리의 다른 글
리액트 테스트 : 라이브러리 없이 Counter 테스트하기 (0) | 2022.06.26 |
---|---|
CSS 애니메이션 : 접근성 (0) | 2022.06.26 |
CSS 애니메이션 : 성능 (0) | 2022.06.26 |
CSS 애니메이션 : Keyframe 응용 (0) | 2022.06.25 |
CSS 애니메이션 : Keyframe (0) | 2022.06.25 |