requestAnimation与滚动
# 对于 requestAnimationFrame 的理解
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
这种方式比传统的setTimeout更加精准,因为requestAnimationFrame会在浏览器重绘之前执行,从而减少了时间误差。
requestAnimationFrame (opens new window)
# 使用 requestAnimationFrame写一个精准的定时器
/**
* 使用requestAnimationFrame实现的精准定时器
* @param {Function} callback - 需要执行的回调函数
* @param {number} delay - 延迟时间,单位为毫秒
*/
function rafTimer(callback, delay) {
let start = null;
let rafId;
// requestAnimationFrame的回调函数
const step = (timestamp) => {
// 初始化开始时间
if (!start) start = timestamp;
// 计算经过的时间
const progress = timestamp - start;
// 如果经过的时间大于等于设置的延迟时间,则执行回调函数
if (progress >= delay) {
callback();
} else {
// 否则继续下一帧
rafId = requestAnimationFrame(step);
}
};
// 开始执行
rafId = requestAnimationFrame(step);
// 返回一个函数,用于取消定时器
return () => {
cancelAnimationFrame(rafId);
};
}
// 使用示例
const cancelRafTimer = rafTimer(() => {
console.log('执行回调');
}, 2000);
// 如果需要取消定时器,可以调用返回的函数
// cancelRafTimer();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 使用 requestAnimationFrame 实现滚动
/**
* 使用requestAnimationFrame实现平滑滚动
* @param {Element} element - 需要滚动的元素
* @param {number} target - 目标滚动位置
* @param {number} duration - 滚动持续时间,单位为毫秒
*/
function smoothScroll(element, target, duration) {
let start = element.scrollTop,
change = target - start,
currentTime = 0,
increment = 20;
const animateScroll = function() {
// 增加时间
currentTime += increment;
// 计算当前动画进度
const val = easeInOutQuad(currentTime, start, change, duration);
// 设置滚动位置
element.scrollTop = val;
// 如果当前时间小于总持续时间,继续下一帧动画
if (currentTime < duration) {
requestAnimationFrame(animateScroll);
}
};
// 缓动函数 - 二次方的缓动(t^2)
function easeInOutQuad(t, b, c, d) {
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
}
animateScroll();
}
// 使用示例
// 假设有一个元素需要滚动,id为"scrollContainer"
const scrollContainer = document.getElementById('scrollContainer');
// 调用smoothScroll函数,滚动到100px的位置,持续时间为500毫秒
smoothScroll(scrollContainer, 100, 500);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
这段代码定义了一个smoothScroll
函数,它接收三个参数:需要滚动的元素、目标滚动位置和滚动持续时间。函数内部使用了requestAnimationFrame
来实现平滑滚动效果,并通过缓动函数easeInOutQuad
来计算每一帧的滚动位置,使得滚动动画更加平滑自然。使用时只需传入相应的参数即可实现平滑滚动效果。
最近更新~: 2024/08/19, 01:05:55