最近LOL六周年官网网页得到了更新,里面出现了这样的一个动画:
我看这个动画挺有意思的,想看看是怎么做的,就通过检查元素看了下。
本来以为是通过canvas
做的,没想到看到了这样的背景图:
其原理就是一帧一帧的变化,就像做动画一样。
动画原理
动画是通过连续播放一系列静止的画面,当连续播放达到一定的速度时,我们用肉眼看到的就是动画了。它的基本原理与电影,电视一样,都是利用视觉原理。医学已经证明,人的眼睛具有“视觉暂留”特性,就是人的眼睛看到一幅画面或一个物体后,在1/24秒内不会消失,利用这一视觉变化效果。因此电影采用了每秒24幅画的速度拍摄播放,电视采用了每秒25幅(PAL制)或30幅(NSTC制)画面的速度拍摄播放,如果以每秒低于24幅画面的速度拍摄播放,就会出现停顿现象。
帧频:即每秒播放的帧数。帧频的大小直接影响到动画的快慢。帧频的单位是“帧/秒”,即“fps”,flash中默认为12fps.由于计算机显示器的荧光刷新特性,实际看到的相当于24帧,刚好达到了动画的一般要求。
仔细一想,的确,要实现这样的动画,感觉真的很难,太费时间了。
对于很复杂的动画,完全可以把动画截成一帧一帧的图片,然后通过一定的速度去更替。
下面是这个动画的代码:
HTML
<html>
<body>
<div class="animate_div"></div>
</body>
</html>
CSS
.animate_div {
width: 280px;
height: 90px;
background-image: url(./images/btn1_sprite.png);
background-repeat: no-repeat;
}
/*下面这部分是直接复制的原网页的*/
.animate_div.ans_btn1 {
background-position: 0 0;
}
.animate_div.ans_btn2 {
background-position: -280px 0;
}
.animate_div.ans_btn3 {
background-position: -560px 0;
}
.animate_div.ans_btn4 {
background-position: 0 -90px;
}
.animate_div.ans_btn5 {
background-position: -280px -90px;
}
.animate_div.ans_btn6 {
background-position: -560px -90px;
}
.animate_div.ans_btn7 {
background-position: 0 -180px;
}
.animate_div.ans_btn8 {
background-position: -280px -180px;
}
.animate_div.ans_btn9 {
background-position: -560px -180px;
}
.animate_div.ans_btn10 {
background-position: 0 -270px;
}
.animate_div.ans_btn11 {
background-position: -280px -270px;
}
.animate_div.ans_btn12 {
background-position: -560px -270px;
}
.animate_div.ans_btn13 {
background-position: 0 -360px;
}
.animate_div.ans_btn14 {
background-position: -280px -360px;
}
.animate_div.ans_btn15 {
background-position: -560px -360px;
}
.animate_div.ans_btn16 {
background-position: 0 -450px;
}
.animate_div.ans_btn17 {
background-position: -280px -450px;
}
.animate_div.ans_btn18 {
background-position: -560px -450px;
}
.animate_div.ans_btn19 {
background-position: 0 -540px;
}
.animate_div.ans_btn20 {
background-position: -280px -540px;
}
.animate_div.ans_btn21 {
background-position: -560px -540px;
}
.animate_div.ans_btn22 {
background-position: 0 -630px;
}
.animate_div.ans_btn23 {
background-position: -280px -630px;
}
.animate_div.ans_btn24 {
background-position: -560px -630px;
}
.animate_div.ans_btn25 {
background-position: 0 -720px;
}
JavaScript
let i = 1
let div = document.getElementsByClassName('animate_div')[0]
let className = 'ans_btn' + i
// 每隔一段时间更换背景图
const run = function () {
if (i > 25) {
i = 1
}
div.classList.remove(className) //移除之前的背景类
className = 'ans_btn' + i
div.classList.add(className) //添加当前背景类
i++
setTimeout(run, 50)
}
run()
根据@荷塘白露的建议,其实可以通过单纯js
来实现动画, 而不需要写那么多CSS
。
注意到原图是每排三个,那么我们可以这样写达到同样的效果:
let div = document.getElementsByClassName('animate_div')[0]
let i = 0
const run = function () {
i = i > 23 ? 0 : i+1
div.style.backgroundPosition = -i%3*280 + 'px ' + -Math.floor(i/3)*90 + 'px'
setTimeout(run, 50)
}
run()
纯CSS版
根据@甜虾的建议,可以使用CSS
的steps
来实现,这个可能存在兼容问题。纯CSS版本可能有些帧没显示到。
<html>
<head>
<style>
.animate_div {
width: 280px;
height: 90px;
background-image: url(./images/btn1_sprite.png);
background-repeat: no-repeat;
animation: play_x 300ms steps(3) infinite;
animation: play_y 900ms steps(8) infinite;
}
@keyframes play_x {
from {
background-position: 0px 0;
}
to {
background-position: -560px 0;
}
}
@keyframes play_y {
from {
background-position: 0px 0;
}
to {
background-position: 0 -720px;
}
}
</style>
</head>
<body>
<div class="animate_div"></div>
</body>
</html>