CSS 和 JS 实现持续的动画效果

sf 上看到一个问题, js 是怎么实现持续的动画效果的? 第一时间想到的是定时器, 后来看到有答案提到了 requestAnimationFrame, 由于之前没有对相关方法有所了解, 于是便去查了下, 顺便也复习了下 animation 的使用.

animation(CSS)

兼容性与属性

猛戳这里查看兼容性

  • animation-name: 动画名称
  • animation-duration: 动画时长
  • animation-timing-function: 动画执行方式
  • animation-delay: 动画延迟执行时间
  • animation-iteration-count: 动画执行次数
  • animation-direction: 是否反向执行动画
  • animation-fill-mode: 动画执行前后的样式

实例

jsfiddle预览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.box {
width: 200px;
height: 200px;
background-color: aqua;
position: absolute;
left: 0;
top: 0;
animation: test 3s linear 2s infinite;
}
@keyframes test {
from {
}
to {
width: 50px;
height: 50px;
background-color: red;
opacity: 0.5;
left: 500px;
top: 500px;
}
}
1
<div class="box"></div>

requestAnimationFrame(JS)

兼容性与基本概念

猛戳这里查看兼容性

优势:

  • 浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果
  • 一旦页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了CPU、GPU和电力

可以使用 cancelAnimationFrame 清除动画

举例

jsfiddle预览

1
2
3
4
5
6
7
8
9
10
11
#anim {
position: absolute;
left: 0px;
width: 150px;
height: 150px;
background: blue;
font-size: larger;
color: white;
border-radius: 10px;
padding: 1em;
}
1
<div id="anim"> Click here to start animation</div>
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
// 兼容性处理
window.requestAnimFrame = (function() {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
window.setTimeout(callback, 1000 / 60)
}
)
})()

var elem = document.getElementById('anim')
var startTime = undefined

function render(time) {
time = Date.now()
if (startTime === undefined) {
startTime = time
}
elem.style.left = ((time - startTime) / 10) % 500 + 'px'
}

elem.onclick = function() {
;(function animloop() {
render()
requestAnimFrame(animloop, elem)
})()
}

参考

requestAnimationFrame MDN

requestanimationframe

animation MDN