[Web] 웹 애니메이션의 이해

애니메이션
애니메이션은 반복적인 움직임의 처리이다. 웹 ui 애니메이션은 자바스크립트로 다양하게 제어할 수 있지만, 규칙적이고 비교적 단순한 방식으로 동작되는 방식은 CSS3의 transition과 transform 속성을 사용해서 대부분 구현가능하다. 뿐만 아니라 자바스크립트보다 더 빠른 성능을 보장한다. 특히 모바일웹에서는 CSS를 사용한 방법이 훨씬 더 빠르다.

FPS
FPS(frame per soecond)는 1초에 화면에 표현할 수 있는 정지화면(frame)의 수 다. 매끄러운 애니메이션은 보통 60fps이고 따라서 16.666초 간격으로 frame 생성이 필요하다. 결국 다음과 같이 정의할 수 있다.
간단하고 규칙적인 것 - css로 변경
세밀한 조작이 필요한 것 - JavaScript로 변경

성능만 봐서는 대체로 CSS로 변경하는 것이 빠르지만 경우에 맞게 두개를 적절히 섞어서 쓰는 것이 중요하다.

자바스크립트에서 애니메이션을 구현하는 메소드 몇가지를 알아보자.

1. setInterval();
주어진 시간에 따라 함수 실행이 가능하다.
1
2
3
4
5
const interval = window.setInterval(()=> {
  console.log('현재시각은'new Date());
},1000/60);
window.clearInterval(interval);
cs
(arrow function이 사용되었음)
하지만 이벤트가 지연되는 경우가 있기때문에 정해진 시간에 함수가 제때 실행된다고 보장할 수 없다.


마우스 클릭 콜백이 발생하여 interval 함수가 실행되지 않는 예시 그림이다. 따라서 일반적으로 setInterval을 사용하는 애니메이션 구현은 잘 쓰이지 않는다.

2. setTimeout
1
2
3
4
5
6
7
8
9
10
let count = 0;
function animate() {   
  setTimeout(() => {
    if(count >= 20return;
    console.log('현재시각은'new Date());
    count++;
    animate();
  },500);
}
animate();
cs

비동기 함수인 setTimeout을 재귀함수로 호출해 항상 제때 시작되도록 보장되는 애니메이션을 만들 수 있다. setTimeut도 엄밀히 말하면 어떤 이유로 인해 제때 원하는 콜백함수가 실행되지 못하고, 지연이 발생할 수 는 있다. 하지만 그럼에도 setTimeout은 매 순간 timeout을 조절할 수 있는 코드구현이 가능하다는 점이 setInterval과의 차이점이다.

참고 : https://javascript.info/settimeout-setinterval


3. requestAnimationFrame()

애니메이션 구현에 가장 최적화된 메서드다.

1
2
3
4
5
6
7
8
9
10
11
12
var count = 0;
var el = document.querySelector(".outside");
el.style.left = "0px";
function run(){
    if(count>30return;
    count=count+5;
    el.style.left = parseInt(el.style.left)+count+"px";
    requestAnimationFrame(run);
}
requestAnimationFrame(run);
cs

먼저 위 예제처럼 requestAnimationFrame을 한번 실행시켜줘야한다. 그 이후 특정 조건이 될 때까지 계속 함수를 호출해주는 것이다. 이렇게 requestAnimationFrame함수를 통해 원하는 함수를 인자로 넣어주면 브라우저는 인자로 받은 비동기 함수가 실행 될 가장 적절한 타이밍에 실행시켜준다.

4. CSS3 transition활용
transition을 이용한 방법이다. 이 방법이 자바스크립트로 구현하는 것보다 더 빠르다고 알려져있다. 특히 모바일웹에서 많이 사용된다.

1
2
transform: scale(1);
transition: left 0.5s ease-in-out;
cs

html element에 이런 속성들을 css로 넣어주고 js로 조작해보자. 
html에는 .outside 라는 div 엘리먼트와 button이 하나 존재한다. 

1
2
3
4
5
6
7
var btn = document.querySelector("button");
var target = document.querySelector(".outside");
 
btn.addEventListener("click",function() {
    var pre = parseInt(target.style.left);
    target.style.left = pre+100+"px";
})
cs

버튼을 클릭 할 때마다 left값이 늘어나면서 element가 오른쪽으로 밀려나는 방식이다.

예제 : 왼쪽 상단에 있는 엘리먼트를 마우스를 올리면 화면 오른쪽 밑으로 이동시키기

1
2
3
4
5
6
var target = document.querySelector(".outside");
 
target.addEventListener("mouseover",function(){
    target.style.transform="translate("+parseInt(window.innerWidth)+"px,"+parseInt(window.innerHeight)+"px)";
 
})
cs

 * 엘리먼트의 postion은 꼭 relative로 지정해야한다. 


No comments:

Powered by Blogger.