canvas动画摸索中……

js动画很多时候用到的是定时器。

1
2
setInterval()
setTimeout()

这两个命令应该是使用频率较高,总的来说会出现一些意向不到的bug,比方说累积延迟,设定的时间间隔上与执行时间的不一致。从而导致执行的频率大大增加,还有回掉函数需要精细化控制,屏幕刷新率。
推荐使用

1
window.requestAnimateFrame()

但是呢?requestAnimateFrame在不同内核浏览器中总是会存在各种各样的兼容性的问题,下面是requestAnimateFrame兼容式写法

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
window.requestNextAnimationFrame =
(function () {
var originalWebkitRequestAnimationFrame = undefined,
wrapper = undefined,
callback = undefined,
geckoVersion = 0,
userAgent = navigator.userAgent,
index = 0,
self = this;

// Workaround for Chrome 10 bug where Chrome
// does not pass the time to the animation function

if (window.webkitRequestAnimationFrame) {
// Define the wrapper

wrapper = function (time) {
if (time === undefined) {
time = +new Date();
}
self.callback(time);
};

// Make the switch

originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;

window.webkitRequestAnimationFrame = function (callback, element) {
self.callback = callback;

// Browser calls the wrapper and wrapper calls the callback

originalWebkitRequestAnimationFrame(wrapper, element);
}
}

// Workaround for Gecko 2.0, which has a bug in
// mozRequestAnimationFrame() that restricts animations
// to 30-40 fps.

if (window.mozRequestAnimationFrame) {
// Check the Gecko version. Gecko is used by browsers
// other than Firefox. Gecko 2.0 corresponds to
// Firefox 4.0.

index = userAgent.indexOf('rv:');

if (userAgent.indexOf('Gecko') != -1) {
geckoVersion = userAgent.substr(index + 3, 3);

if (geckoVersion === '2.0') {
// Forces the return statement to fall through
// to the setTimeout() function.

window.mozRequestAnimationFrame = undefined;
}
}
}

return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||

function (callback, element) {
var start,
finish;

window.setTimeout( function () {
start = +new Date();
callback(start);
finish = +new Date();

self.timeout = 1000 / 60 - (finish - start);

}, self.timeout);
};
}
)
();