CSS Serials - Beach Ball

程序员的学习之路上,提高自己的技术水平的一种非常有效的方式,就是分析和学习优秀的项目代码。在CSS Serials系列的文章,我会从自己的角度来分析这些项目实现的原理,并进行一定的扩展,希望能够对阅读这些文章的你有所帮助。

今天分析的项目是使用CSS3輕鬆寫出MAC彩虹球效果,一个纯CSS实现彩虹球效果的项目。

首先我们先看下项目的效果

See the Pen MAC Beach ball - PURE CSS by Justin Yang (@justinyang) on CodePen.

HTML

我们首先观察下项目的HTML代码

html
1
2
3
4
<div class="load">
<div class="light"></div>
<div class="ball"></div>
</div>

HTML结构非常简单,一个外部容器div.load,一个灯光效果div.light,以及一个彩虹球div.ball。div.light主要是为了让外边缘的感觉更加平顺,实现比较简单,这里就不详细分析。后面主要分析div.load和div.light的CSS代码。

CSS

css
1
2
3
4
5
6
7
8
9
10
11
12
.load {
position:absolute;
left:0;
top:0;
right:0;
bottom:0;
margin:auto;
width:50px;
height:50px;
border-radius:50%;
box-shadow:0 0 10px rgba(0,0,0,.5);
}

容器div.load的样式中,需要关注的点就是元素的居中。关于元素居中的方式,可以参看【CSS TRICK】垂直居中

css
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
.ball {
// 第一部分
width:100%;
height:100%;
border-radius:50%;
// 第二部分
background-size:50% 50%;
background-position:
left top,left top,left top,
right top,right top,right top,
right bottom,right bottom,right bottom,
left bottom,left bottom,left bottom;
background-repeat:no-repeat;
background-image:
-moz-linear-gradient(60deg, #ff0000 36%,rgba(255,0,0,0) 36% ),
-moz-linear-gradient(30deg, #ff8000 64%,rgba(255,128,0,0) 64% ),
-moz-linear-gradient(0deg, #ffff00 100%,rgba(255,255,0,0) 100% ),
-moz-linear-gradient(-30deg, #80ff00 36%,rgba(128,255,0,0) 36%),
-moz-linear-gradient(-60deg, #00ff80 64%,rgba(0,255,128,0) 64% ),
-moz-linear-gradient(0deg, #00ffff 100%,rgba(0,255,255,0) 100% ),
-moz-linear-gradient(-120deg, #3097ff 36%,rgba(48,151,255,0) 36%),
-moz-linear-gradient(-150deg, #3071ff 64%,rgba(48,113,255,0) 64% ),
-moz-linear-gradient(0deg, #3e30ff 100%,rgba(62,48,128,0) 100% ),
-moz-linear-gradient(150deg, #5f3b9d 36%,rgba(95,59,157,0) 36% ),
-moz-linear-gradient(120deg, #803198 64%,rgba(128,49,152,0) 64% ),
-moz-linear-gradient(0deg, #ff0080 100%,rgba(255,0,128,0) 100% );
background-image:
-webkit-linear-gradient(60deg, #ff0000 36%,rgba(255,0,0,0) 36% ),
-webkit-linear-gradient(30deg, #ff8000 64%,rgba(255,128,0,0) 64% ),
-webkit-linear-gradient(0deg, #ffff00 100%,rgba(255,255,0,0) 100% ),
-webkit-linear-gradient(-30deg, #80ff00 36%,rgba(128,255,0,0) 36%),
-webkit-linear-gradient(-60deg, #00ff80 64%,rgba(0,255,128,0) 64% ),
-webkit-linear-gradient(0deg, #00ffff 100%,rgba(0,255,255,0) 100% ),
-webkit-linear-gradient(-120deg, #3097ff 36%,rgba(48,151,255,0) 36%),
-webkit-linear-gradient(-150deg, #3071ff 64%,rgba(48,113,255,0) 64% ),
-webkit-linear-gradient(0deg, #3e30ff 100%,rgba(62,48,128,0) 100% ),
-webkit-linear-gradient(150deg, #5f3b9d 36%,rgba(95,59,157,0) 36% ),
-webkit-linear-gradient(120deg, #803198 64%,rgba(128,49,152,0) 64% ),
-webkit-linear-gradient(0deg, #ff0080 100%,rgba(255,0,128,0) 100% );
// 第三部分
-webkit-animation:mymy 1s infinite linear;
-moz-animation:mymy 1s infinite linear;
}

@-webkit-keyframes mymy{
0%{ transform:rotate(0);}
100%{transform:rotate(360deg);}
}

@-moz-keyframes mymy{
0%{ transform:rotate(0);}
100%{transform:rotate(360deg);}
}

按照不同的内容,我将这些代码分成了三部分,下面我们逐个分析:

1) 第一部分的三行代码,是用来设置元素的大小和圆角,其中border-radius:50%;将元素的圆角设置成50%,就可以变成圆形图案。

2) 用来设置元素的背景,这些也是整个项目的难点和亮点。

首先,对于彩虹球,我们可以将其分成4大块,左上角、右上角、左下角和右下角,每一部分的宽和高都是整体的50%。然后每部分里包含3小块,也就是总共12块,每一块的背景颜色都各不相同。

这里我们需要使用到multiple background images技术,语法和说明可以参考MDN的Using CSS multiple backgrounds一文。

回到我们实现代码中,这里background-size:50% 50%;将background的大小设置成元素的四分之一(对应4大块的大小)。

然后利用background-position

css
1
2
3
4
5
background-position:
left top,left top,left top,
right top,right top,right top,
right bottom,right bottom,right bottom,
left bottom,left bottom,left bottom;

将每一小块的背景放置到相应的四个角落。

接着使用linear-gradient来设置背景图。

对照linear-gradient的语法

css
1
background: linear-gradient(direction, color-stop1, color-stop2, ...);

我们可以发现,在实现中

css
1
-moz-linear-gradient(60deg, #ff0000 36%,rgba(255,0,0,0) 36%)

非常巧妙地在后面的color stop使用了rgba(255,0,0,0)透明色,并且将它的位置设置成第一个的位置,这样两个颜色之间就不会出现过度区。

相似的方式也可以查看这个例子中backgroun-image的设置。

通过调整不同的角度,就可以实现出不同色块的背景图。然后利用相互之间的遮盖,就可以达到我们想要的效果了。

3) 通过animation来使得彩虹球不停的旋转

css
1
2
3
4
5
6
7
8
9
10
11
12
-webkit-animation:mymy 1s infinite linear;
-moz-animation:mymy 1s infinite linear;

@-webkit-keyframes mymy{
0%{ transform:rotate(0);}
100%{transform:rotate(360deg);}
}

@-moz-keyframes mymy{
0%{ transform:rotate(0);}
100%{transform:rotate(360deg);}
}

关于CSS的动画,可以参看CSS Animation