> 웹 프론트엔드 > JS 튜토리얼 > 자바스크립트 애니메이션 구현 원리에 대한 간략한 분석_javascript 기술

자바스크립트 애니메이션 구현 원리에 대한 간략한 분석_javascript 기술

WBOY
풀어 주다: 2016-05-16 16:11:45
원래의
1153명이 탐색했습니다.

다음과 같은 애니메이션 기능 요구 사항이 있다고 가정해 보겠습니다. div의 너비를 100px에서 200px로 변경하세요. 작성된 코드는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.


함수 animate1(요소, endValue, 기간) {
var startTime = 새 날짜(),
         startValue =parseInt(element.style.width),
         단계 = 1;
 
var 타이머Id = setInterval(function() {
        var nextValue = parseInt(element.style.width) 단계;
          element.style.width = nextValue 'px';
If (nextValue >= endValue) {
              clearInterval(timerId);
// 애니메이션을 표시하는데 시간이 걸립니다
               element.innerHTML = 새 날짜 - startTime;
}
}, 기간 / (endValue - startValue) * 단계);
}

animate1(document.getElementById('test1'), 200, 1000);


200px이 될 때까지 일정한 간격으로 1px씩 늘려가는 것이 원칙입니다. 하지만 애니메이션 종료 후 표시 시간이 1초 이상(보통 1.5초 정도)입니다. 그 이유는 setInterval이 실행 간격을 엄격하게 보장하지 않기 때문입니다.

더 좋은 방법이 있나요? 초등학교 수학 문제를 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.

A동과 B동은 100m 떨어져 있습니다. 한 사람이 A동에서 B동까지 일정한 속도로 걸어가서 5분 동안 목적지에 도달합니다.

등속운동의 특정 순간의 거리를 계산하는 계산식은 거리 * 현재 시간 / 시간입니다. 따라서 답은 100 * 3/5 = 60 이어야 합니다.

이 질문에서 영감을 얻은 것은 특정 순간의 거리가 특정 공식을 통해 계산될 수 있다는 것입니다. 마찬가지로 애니메이션 진행 중 특정 순간의 값도 누적하는 대신 공식을 통해 계산할 수 있습니다.

코드 복사 코드는 다음과 같습니다.


함수 animate2(요소, endValue, 기간) {
var startTime = 새 날짜(),
         startValue =parseInt(element.style.width);

var 타이머Id = setInterval(function() {
      var 백분율 = (새 날짜 - 시작 시간) / 기간;

var stepValue = startValue (endValue - startValue) * 백분율;
          element.style.width = stepValue 'px';

if (백분율 >= 1) {
              clearInterval(timerId);
                element.innerHTML = 새 날짜 - startTime;
}
}, 13);
}

animate2(document.getElementById('test2'), 200, 1000);

이번 개선 이후에는 애니메이션 실행 시간이 최대 10ms 정도의 오차만 발생하는 것을 확인할 수 있습니다. 그러나 문제가 완전히 해결되지는 않았습니다. 브라우저 개발 도구에서 test2 요소를 확인하면 test2의 최종 너비가 200px 이상이 될 수 있음을 알 수 있습니다. animate2 함수의 코드를 주의 깊게 살펴보면 다음과 같은 사실이 드러납니다.

1.percentage의 값은 1보다 클 수 있는데, 이는 Math.min을 통해 최대값을 제한하여 해결할 수 있습니다.
2. 백분율 값이 1보다 크지 않음이 보장되더라도 endValue 또는 startValue가 소수이면 (endValue - startValue) * 백분율 값은 Javascript 소수 연산의 정밀도가 다음과 같기 때문에 여전히 오류가 발생할 수 있습니다. 충분하지 않습니다. 실제로 우리가 보장하고 싶은 것은 최종 값의 정확성이므로 백분율이 1인 경우 endValue를 직접 사용하면 됩니다.

따라서 animate2 함수의 코드는 다음과 같이 수정됩니다.

코드 복사 코드는 다음과 같습니다.

함수 animate2(요소, endValue, 기간) {
var startTime = 새 날짜(),
         startValue =parseInt(element.style.width);

var 타이머Id = setInterval(function() {
​​​​ // 백분율이 1보다 크지 않은지 확인하세요
      var 백분율 = Math.min(1, (새 날짜 - 시작 시간) / 기간);

var stepValue;
If (백분율 >= 1) {
​​​​​​ // 최종 값의 정확성 보장
             stepValue = endValue;
         } else {
             stepValue = startValue (endValue - startValue) * 백분율;
}
          element.style.width = stepValue 'px';

if (백분율 >= 1) {
              clearInterval(timerId);
                element.innerHTML = 새 날짜 - startTime;
}
}, 13);
}

마지막 질문이 하나 있습니다. setInterval 간격이 13ms로 설정된 이유는 무엇입니까? 그 이유는 현재 모니터의 주사율이 일반적으로 75Hz를 넘지 않기 때문입니다. 즉, 초당 75회, 즉 약 13ms마다 주사율을 동기화하는 것이 좋습니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿