애니메이션
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>
출처
'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 |