Web/Frontend

웹 애니메이션 - requestAnimation, transition

WakaraNai 2021. 5. 23. 07:41
728x90
반응형

애니메이션

element가 좌우로 움직인다거나 사라질 때 점점 작아지면서 사라지는 것,

스크롤과 브라우저의 이동에 반응하여 브라우저가 다시 렌더링하는 과정

 

끊김없이 부드럽게 움직이는 방법을 고민하는 과정

 

CSS3의 transition과 transform 속성을 사용해서 구현 가능

js보다 더 빠름.

특히 모바일 웹에서는 CSS가 더욱 빠름

 

정리하면

간단하고 규칙적인 것 -> css

세말한 조작이 요하는 것 -> js

 

 

FPS

frame per second 초당 정지 화면 수

 매끄러운 애니메이션은 보통 60fps

 

 

JS 애니메이션

setInterval( 콜백함수, 실행간격)

개발자도구의 console 탭에서 실행해보기

//const interval = window.setInterval(()=> {
//  console.log('현재시각은', new Date());
//},1000/60);

//window.clearInterval(interval);

window.setInterval(()=> {
  console.log('현재시각은', new Date());
},1000/60);

 

아래 사진을 보면 제때 일어나야 할 이벤트 콜백이 지연되거나, 없어지는 것을 알 수 있음

이로 인해 setInterval로 정해진 시간에 함수가 실행된다고 보장할 수 없음

1초라고 지정해도 2초 후에 실행되는 일이 간혹 발생함

 

그래서 일반적으로 이 함수로 애니메이션을 구현하지 않음

 

 

 

 

setTimeout(콜백함수, 지연시간)

이 함수도 예기치 않은 이유로 콜백함수가 제때 실행되지 않을 수 있음

그럼에도 setTimeout은 코드로 매 순간 timeout을 조절할 수 있다는 점이, setInterval과 다름.

 

지정된 시간 이후에 한 번만 콜백함수를 실행

콜백함수 안에서 자기 자신을 재귀호출하여 여러번 실행할 수 있음 

이전 함수가 끝난 다음에 다음 함수가 호출되기에 순차적으로 진행되어 조금 더 일정한 실행을 보장함.

animate() 함수 호출 확인하기

let count = 0;
function animate() {   
  setTimeout(() => {
    if(count >= 20) return;
    console.log('현재시각은', new Date());
    count++;
    animate();
  },500);
}
animate();

500 간격이라서

0.5초 간격으로 한 번씩 실행됨

 

 

 

 

 

 

 

 

 

 

requestAnimationFrame

위 함수들의 지연 문제를 해결해주는 애니메이션 용 함수

cavnas, svg로 복잡한 애니메이션을 다룰 때 이 함수가 특히 유용함

 

fps 에서 딱 한 장을 구현함

 

먼저 아래처럼 requestAnimationFrame을 한 번 실행해야 함

그 이후에 특정 조건이 될 때까지 (함수의 탈출 조건) 함수를 연속적으로 호출

원하는 함수를 인자로 넣어주면 브라우저는 그 비동기 함수가 실행될 가장 적절한 타이밍에 실행시켜 줌

브라우저를 믿고 함수를 전달하는 것

 

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .outside {
      position: relative;
      background-color: blueviolet;
      width: 100px;
      font-size: 0.8rem;
      color: #fff;
    }
  </style>
</head>

<body>
  <div class="outside">제가 좋아하는 과일은요...</div>
</body>

</html>
var count = 0;
var el=document.querySelector(".outside");
el.style.left = "0px"; // 초기값

function run() {
   if(count > 70) return;
   count = count + 1;
   // 숫자로 변환하는 과정 필요
   el.style.left =  parseInt(el.style.left) + count + "px";
   // 점점 왼쪽으로
   requestAnimationFrame(run);
}

requestAnimationFrame(run);

// window.requestAnimationFrame(callback);
// widonw. 생략 가능

 

예제에서는 연속적으로 requestAnimationFrame으로 run함수를 호출하여 left값을 증가시킴 (70번만)

count 변수로 횟수를 지정하여 동작하게 했지만

시간값을 이용하면 일정 시간 동안만 애니메이션이 동작하게 할 수 있음

 

// 또 다른 예제

const element = document.getElementById('some-element-you-want-to-animate');
let start;

function step(timestamp) {
  if (start === undefined)
    start = timestamp;
  const elapsed = timestamp - start;

  // `Math.min()` is used here to make sure that the element stops at exactly 200px.
  // 오른쪽으로 0.1px/ms 속도로 이동
  element.style.transform = 'translateX(' + Math.min(0.1 * elapsed, 200) + 'px)';
  // 요소의 최종 위츼는 0.1*2000초 후인, 오른쪽으로 200px

  if (elapsed < 2000) { // 2초 간격으로 애니메이션 정지
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

 

참고

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame 

 

 

 

CSS와 JS 활용

GPU 가속을 이용하는 속성들에 대해서 배워봅시다

IDE에서 작성한 뒤 실행해보세요

transition 으로 어떤 애니메이션의 실행 간격과 그 방식을 조정하면 편리합니다.

 

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
    .outside {
      position: relative;
      background-color: blueviolet;
      width: 100px;
      font-size: 0.8rem;
      color: #fff;
      top: 100px;

      transform: scale(1);
      transition: left 0.5s ease-in-out;
    }
  </style>
</head>

<body>
  <div class="outside" style="left:100px;">제가 좋아하는 과일은요...</div>
  <button>right</button>
</body>
<script src="test.js"></script>

</html>
var target = document.querySelector(".outside");
var btn = document.querySelector("button");

btn.addEventListener("click", function () {
  var pre = parseInt(target.style.left);
  target.style.left = pre + 200 + "px";
});

 

 

CSS3의 GPU가속 속성들 

 

  • transform : translateXX();
  • transform : scale();
  • transform : rotate();
  • opacity

 

 

Vendor Prefix

유명한 웹 브라우저 공급자가 새로운 실험적인 기능을 제공할 때

이전 버전의 웹 브라우저에 그 사실을 알려주기 위해 사용하는 접두사를 의미합니다.

즉 아직 CSS 권고에 포함되어 있지 않거나 완벽히 제정된 기능이 아닐 때 vendor prefix를 사용합니다.

그러면 해당 기능이 포함되지 않은 이전 버전의 웹 브라우저에서도 그 기능을 사용할 수 있습니다.

이후에 CSS 권고에 포함되거나 제정되면 더는 사용할 필요가 없어집니다.

 

주요 웹 브라우저가 사용하는 vendor prefix 입니다.

크롬과 사파리는 같은 웹킷 계열 브라우저이므로 동일합니다.

<style>
    .button {
        background: red;          <!-- gradient 속성을 지원하지 않는 모든 브라우저를 위한 코드 -->

        background: -webkit-linear-gradient(red, yellow); <!-- 크롬과 사파리 4.0 이상을 위한 코드 -->

        background: -moz-linear-gradient(red, yellow);    <!-- 파이어폭스 3.6 이상을 위한 코드 -->

        background: -ms-linear-gradient(red, yellow);     <!-- 익스플로러 10.0 이상을 위한 코드 -->

        background: -o-linear-gradient(red, yellow);      <!-- 오페라 10.0 이상을 위한 코드 -->

        background: linear-gradient(red, yellow);         <!-- CSS 표준 문법 코드 -->
    }
</style>

 

출처

http://tcpschool.com/css/css3_module_vendorPrefix

728x90
반응형

'Web > Frontend' 카테고리의 다른 글

Event Delegtion - 등록, 버블링, 멈추기  (0) 2021.05.25
디렉토리 구성 방식 - JS&CSS  (0) 2021.05.24
AJAX - 개발자도구의 Network 탭  (0) 2021.05.21
DOM Node(API) 조작하기  (0) 2021.05.19
AJAX  (0) 2021.05.07