function callback(time) {
window.mozRequestAnimationFrame(콜백);
doWork()
}
doWork()가 1000/60밀리초가 걸리는 경우 프레임 속도는 약 30fps이고 동일한 애니메이션이 setTimeout(콜백, 16)을 사용하는 경우 프레임 속도는 60fps입니다. 콜백이 실행되기 시작한 후 16ms가 아닌 콜백이 실행된 후 약 16ms 후에 항상 콜백이 다시 실행되기 시작하는 것 같습니다. 후자이고 계산 속도가 충분히 빠르면 60fps 프레임을 생성할 수 있습니다.
표준 컨트롤이라면 포털이 여기 있습니다
더 이상 고민하지 말고 클래식 애니메이션 기능부터 시작해 보세요:
function animate(element, name, from, to, time) {
time = 시간 || 800; //기본값 0.8초
var style = element.style,
latency = 60, //60ms마다 변경
count = 시간/대기 시간, //변경 횟수
step = Math.round((to - from) / count), //각 단계의 변화량
now = from
function go() {
count--; 🎜>now = count ? now step: to;
style[name] = 이제 'px'
if (count) {
setTimeout(go, Latency)
}
style [name] = from 'px';
setTimeout(go,latency);
}
단위는 px로만 설정할 수 있습니다. 스타일을 수정하세요. 함수 구현 관점에서만 보면 매우 고전적인 애니메이션 개념이라고 할 수 있습니다. 기본 로직은 다음과 같은 부분으로 구성됩니다.
시작점 값과 끝점 값을 가져오고, 애니메이션에 소요되는 시간과 각 감지 지연 시간 요구 사항 간의 간격, 값 변경 횟수 및 각 변경 단계의 양을 계산합니다.
다음 감지로 이동하려면 setTimeout(fn, 대기 시간)을 활성화하세요.
다음 감지에서는 속성 단계를 한 번 설정하고 애니메이션이 아직 종료되지 않은 경우 2단계로 돌아가서 다음 감지를 계속합니다.
이 함수는 매우 잘 작동하며 수천 개의 사이트와 시스템에 서비스를 제공합니다. 실제로 jQuery의 animate 함수의 핵심은 setInterval 함수에 지나지 않습니다.
그러나 현재 시스템의 복잡성이 꾸준히 증가함에 따라 애니메이션 효과가 점점 더 많아지고 애니메이션의 부드러움에 더 많은 관심이 집중되어 위 기능에 몇 가지 문제가 발생합니다. 예를 들어 100개의 애니메이션 효과가 동시에 켜지면 위 함수에 따르면 100개의 타이머가 동시에 실행될 것이 분명하며 이러한 타이머 간의 스케줄링이 성능에 약간의 영향을 미칠 것입니다. 일반적인 환경에서는 이러한 작은 효과가 중요하지 않지만 애니메이션과 같이 유창성에 대한 요구 사항이 높은 환경에서는 미묘한 영향으로 인해 나쁜 사용자 경험이 발생할 수 있습니다.
이러한 상황에서 일부 개발자는 타이머를 사용하여 애니메이션 프레임을 트리거하고 다양한 애니메이션이 이러한 프레임을 각 프레임에 등록하는 통합 프레임 관리를 기반으로 하는 애니메이션 프레임워크를 개발했습니다. 타이머 스케줄링에 따른 오버헤드를 줄일 수 있다는 장점이 있지만, 애니메이션 프레임워크 개발자의 경우 프레임 모니터링을 위한 통합된 프레임 관리 및 API를 개발하고 유지 관리해야 합니다.
직접 브라우저 지원
결국 브라우저 제조업체는 이것이 실제로 수행될 수 있음을 발견했으며 브라우저 수준에 따라 더 많은 최적화가 있을 수 있습니다. 예를 들면 다음과 같습니다. 한 설문조사에서 DOM에 대한 모든 작업에 대해 레이아웃과 페인트는 한 번만 수행됩니다.
애니메이션 요소가 숨겨져 있으면 페인트가 수행되지 않습니다.
이에 따라 브라우저에서는 requestAnimationFrame이라는 API를 출시하기 시작했습니다. 이 함수에 대해서는 MDC의 관련 페이지에 간단히 설명하면 이 함수를 사용하는 방법에는 두 가지가 있습니다.
requestAnimationFrame 함수를 호출합니다. 콜백 매개변수를 전달하면 다음 애니메이션 프레임에서 콜백이 호출됩니다.
매개변수를 전달하지 않고 이 함수를 직접 호출하면 다음 프레임이 트리거될 때 window.onmozbeforepaint 이벤트가 동시에 트리거됩니다. 이 이벤트를 등록하면 애니메이션을 적용할 수 있습니다.
두 번째 방법은 Firefox 자체 이벤트에 의존하며 beforepaint 이벤트가 아직 표준에 진입하지 않았으므로 첫 번째 방법을 사용하지 않는 것이 좋습니다. 이때 애니메이션 로직은 다음과 같습니다.
현재 시간 startTime을 애니메이션이 시작되는 시간으로 기록합니다.
콜백 함수로 다음 프레임을 요청합니다.
다음 프레임이 트리거되면 콜백 함수의 첫 번째 매개변수는 현재 시간이며, 이 값을 startTime과 비교하여 시간 간격 elapseTime을 결정합니다.
ellapseTime이 미리 설정된 애니메이션 시간을 초과했는지 여부를 판단합니다. 초과하는 경우 애니메이션을 종료합니다.
애니메이션 속성 변경의 차이를 계산한 다음 ellapseTime = Difference / time * ellapseTime 동안 변경해야 하는 단계의 양을 결정합니다.
지금으로 변경되어야 하는 Math.round(단계에서) 위치를 계산하고 스타일을 다시 할당합니다.
계속해서 다음 프레임을 요청하세요.
새로운 애니메이션 기능
다음은 새로운 애니메이션 기능입니다. 코드 복사 코드는 다음과 같습니다.
function animate(element, name, from, to, time) {
time = time || 800; // 기본값 0.8초
var style = element.style,
startTime = new Date;
function go(timestamp) {
var Progress = timestamp - startTime;
if (progress >= Duration) {
style[name] = to 'px'; return;
}
var now = (to - from) * (진행률/기간)
style[name] = now.toFixed()
requestAnimationFrame(go); 🎜>}
style[name] = from 'px';
requestAnimationFrame(go);
}
이 시점에서 한 가지 문제가 남습니다. 모든 브라우저가 requestAnimationFrame 기능을 지원하는 것은 아니므로 간단하게 수정해 보세요.
Firefox의 특성에 따르면 mozRequestAnimationFrame이 제공하는 최고 FPS는 60이며 각 프레임의 계산 시간에 따라 조정됩니다. 예를 들어 각 프레임을 계산하는 데 1초가 걸린다면 1FPS만 제공합니다. 애니메이션 효과.
Chrome의 상위 버전에서도 webkitRequestAnimationFrame이라는 이 기능을 구현합니다. 향후 Opera의 oRequestAnimationFrame과 IE의 msRequestAnimationFrame이 있을 것으로 예상되므로 간단한 호환성 프로세스는 다음과 같습니다.
requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || .webkitRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function(callback) { setTimeout(callback, 1000 / 60);