웹 애니메이션
1. 웹 애니메이션 이해와 setTimeout 활용
사용자에게 매끄러운 UX를 지원해주어야 합니다.
1) 애니메이션
반복적 움직임의 처리를 말합니다.
웹 UI 애니메이션은 규칙적이고 단순한 방식으로 동작하는 CSS3의 transition, transform 속성을 사용하여 구현가능합니다.
javascript로도 구현이 가능하지만 그보다 더 빠른 성능을 보장합니다.
특히 모바일웹에서는 CSS 방법이 더 빠릅니다. (특히 transition)
2) FPS
FPS(frame per second)는 1초에 화면에 표현할 수 있는 정지화면(frame) 수 입니다.
매끄러운 애니메이션은 보통 60fps 입니다.
16.666ms 간격으로 frame생성이 필요합니다. (1000ms / 60fps = 16.6666ms)
애니메이션은 CSS의 transition 속성으로 CSS속성을 변경하거나, js로 CSS속성을 변경할 수 있습니다.
CSS : 간단하고 규칙적인 것
Javascript : 세밀한 조작이 필요한 것
3) Javascript 애니메이션
- setInterval
- setTimeout
- requestAnimationFrame
- Animations API
3.1) setInterval()
interval(간격)를 지정해서 매 간격 시간마다 함수를 실행합니다.
interval로 정의 된 것은 비동기적이라 느립니다. 따라서 1초마다 실행하라고 설정해 놓아도 다른 함수가 먼저 실행되면서 정기적으로 실행되지 않을 수 있습니다. 이는 애니메이션 끊김 현상의 원인이 될 수 있습니다.
일어나야할 이벤트 콜백이 지연되고, 없어지는 일이 발생가능합니다. 따라서 setInterval의 사용은 함수가 실행된다고 보장할 수 없습니다.
일반적은 setInterval 사용하는 애니메이션은 잘 구성하지 않습니다.
const interval = window.setInterval(()=> {
console.log('current time:', new Date());
}, 1000);
window.clearInterval(interval);
3.2) setTimeout
방법: setTimeout으로 recursive하게 진행합니다.
다른 이유로 콜백함수가 실행되지 않을 수 있습니다. (setInterval과 같은 문제)
하지만 setTImeout은 매 순간 timeout을 조절할 수 있는, 코드구현으로 컨트롤이 가능한 부분이 있습니다. (setInterval과 다른 점)
3.3) requestAnimationFrame
setTimeout은 애니메이션 주기 16.6 미만의 경우 불필요한 frame이 생성 되는 등 문제가 생깁니다.
requestAnimationFrame은 보완할 수 있습니다. animiation을 위한 전용 함수 입니다.
var count = 0;
var el = document.querySelector(".outside");
el.style.left = "0px";
function run() {
if (count > 30) return;
count += 1;
el.style.left = parseInt(el.style.left) + count + "px";
requestAnimationFrame(run);
}
requestAnimationFrame(run);
연속적으로 requestAnimationFrame을 통해 run함수를 호출하고, left값을 증가해주고 있는 코드입니다.
.outside 클래스에 속한 객체의 위치가 갱신되어서 오른쪽으로 이동하는 것을 볼 수 있습니다.
Canvas, svg 등의 그래픽 작업을 할 경우 복잡한 애니메이션을 다루게 되는데,
js에서 복잡한 애니메이션 처리를 할 때 requestAnimationFrame이 유용하게 사용될 수 있습니다.
관련 MDN사이트
2) CSS3 transition 활용
버벅거리는 효과는 답답하고 느린 웹사이트로 인식될 수 있습니다.
최적의 방법을 찾기 위해 CSS3 효과가 좋습니다.
CSS3의 transition을 사용한 방법이 javascript보다 더 빠릅니다.
특히 모바일 웹에서는 transform을 사용한 element 조작을 주로 구현합니다.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="outside" style="left:100px;">제가 좋아하는 과일은요..</div>
<button>right!</button>
</body>
<script src="animation.js"></script>
</html>
style.css
.outside {
position: relative;
background-color: blueviolet;
width: 100px;
font-size: 0.8em;
color: #fff;
left:"100px";
top:"1000px";
transform: scale(1);
/* transition: all 2s; */
transition: left 0.5s ease-out;
}
animation.js
var base = document.querySelector(".outside");
base.style.transform = "scale(4)";
base.style.left = "300px";
var target = document.querySelector(".outside");
var btn = document.querySelector("button");
btn.addEventListener("click", ()=>{
var prev = parseInt(target.style.left);
target.style.left = prev + 100 + "px";
})
sources > Network에서 디버깅 확인하며 작업하면 편합니다.
좀 더 다양한 효과
ease-in, ease-out
빠른 CSS3 애니메이션
main thread 처리가 아니라,
GPU가속을 이용해서 애닌메이션 처리를 할 수 있습니다.
- transform: translateXX();
- transform: scale();
- transform: rotate();
- opacity
Reference
부스트코스
'lang > javascript web' 카테고리의 다른 글
[Web app] Tab UI 설명, 구현 (607) | 2019.12.31 |
---|---|
[Webapp] Ajax 비동기, 응답처리 (605) | 2019.12.08 |
[Webapp] DOM API, HTML 구조 수정 (599) | 2019.12.07 |
[Webapp] DOM API 탐색, 조작 (579) | 2019.12.06 |
[js] Array, Obejct (671) | 2019.12.05 |
댓글