CSS3制作球体
使用CSS3的border-radius
属性,我们可以制作圆角或圆形。添加一些渐变效果,就能让他们变成球体。让我们来试试,给这些球体添加一些动画,让效果更接近我们的生活。
扁平化设计(Flat design)
我们有两种方法,可以使用CSS来制作球体。
一个是使用大量的元素标签来创建一个3D球体。比如说下面的一个效果:
其最大的缺点就是要使用很多个元素,这样会影响性能。而且这些效果看起来也有点粗糙,球面也不光滑。
另一个方法就是我们接下来要探讨的方法,利用CSS的渐变和阴影在单个元素上创建3D球体效果。
下面内容中提到的例子都可以在Codepen上找到,或者点击Codepen的编辑链接查看每个示例的源码。
示例中的代码,没有为每个浏览器添加对应的私有前缀。我建议使用Autoprefixer插件根据需要添加浏览器私有前缀。
基本形状
在详细介绍示例效果这前,我们先创建一个最简单的圆形形状。那么我们就从HTML开始吧:
<figure class="circle"></figure>
在这里我们使用了<figure>
元素,实际上可以是任何HTML元素。在HTML5中,<figure>
表示的是一幅图像或图像的一部分内容,移除内容也不会影响需要表达的语义。
需要把这个元素创建成一个圆,我样只要给它设置一个宽度和高度,并且设置border-radius
值为50%
。border-radius
值只要超过50%
就能制作一个圆。当然,其前提是元素的width
和height
是相同(即是一个正方形)。
.circle {
display: block;
background: black;
border-radius: 50%;
height: 300px;
width: 300px;
margin: 0;
}
这个时候,你看到的效果如下所示:
现在,我们已经有了一个基本的圆,我们可以在这个基础上添加一些样式,让其变成球形。
CSS其实不仅仅能制作出圆形,其还可以制作出更多图形,如果你对这方面感兴趣,可以阅读早期分享过的《CSS制作图形速查表》和《纯CSS制作的图形效果》。
Shading 101
大多数3D球体的教程做的第一件事情就是添加一个径向渐变,颜色淡一点,并且整圆心偏左一点。
我们可以使用下面的这段CSS代码:
.circle {
display: block;
background: black;
border-radius: 50%;
height: 300px;
width: 300px;
margin: 0;
background: radial-gradient(circle at 100px 100px, #5cabff, #000);
}
这个时候,效果就变成这样:
径向渐变
radial-gradient
属性需要一些参数。第一个是渐变的圆心。在此之前一般是从shape
所在的position
来定。在这个示例中,圆心的位置是(100px,100px)
。
接下来要指定一系列的颜色。你可以指定两个以前的颜色,同时需要给他们指定对应的位置,让他们有一定的距离,使渐变颜色能更好的融入在一起。
本例中指定了两个颜色。第一个颜色从0%
慢慢过渡到位置在100%
位置的颜色。如果我们想要其他的渐变效果,可以指定距离,指定距离可以使用像素或百分比。在接下来的示例中,我们可以看到。
现在的3D效果看起来有点“3D-ish”。没关系,我们可以让其变得更好看一点。
阴影和3D效果
在球面上取用不同的材质,你可以创建出不同的球体效果。首先我们需要有一个地方可以用来创建。
在前面的基础上,我们再添加两个元素:
<section class="stage">
<figure class="ball"><span class="shadow"></span></figure>
</section>
在ball
元素中添加一个span
元素用来创建球体的影子效果,而且把它们放在一个名为stage
的<div>
元素内。这个div.stage
是很有用的,我们可以给其设置一些角度和影子的位置,让3D球体看起来更具3D效果。
给他们应用一些样式代码:
.stage {
width: 300px;
height: 300px;
display: inline-block;
margin: 20px;
perspective: 1200px;
perspective-origin: 50% 50%;
}
.ball .shadow {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.1) 40%, rgba(0, 0, 0, 0) 50%);
transform: rotateX(90deg) translateZ(-150px);
z-index: -1;
}
请注意,在这演示的代码没有添加浏览器前缀,但在Codepen上的示例都已添加了前缀。在上面的示例中,给div.stage
设置了perspective
的值为1200px
。这个perspective
属性对于3D变形来说至关重要。该属性会设置查看者的位置,并将可视内容映射到一个视锥上,继而投到一个2D视平面上。如果不指定透视,则Z轴空间中的所有点将平铺到同一个2D视平面中,并且变换结果中将不存在景深概念。简单点说,perspective
让一个舞台看起来在一个3D场景中。
有关于
perspective
属性的详细介绍,可以阅读《Transform-style和Perspective属性》。
然后使用渐变给球体制作一个阴影,并且给它设置一个transform
效果,转换阴影位置。你可以使用rotate
、scale
、translate
或者skew
在3D空间中改为阴影位置。球体的阴影在X
轴旋转了90deg
,然后Z
轴向下推150px
。
我们给舞台容器stage
设置了一个perspective
值,我们往下看,可以看到一个椭圆形。
现在的效果看起来比以前好多了,接下来给它添加更多的材质效果,让其看起来更像一个3D球体。
着色
在现实世界 中你很难从一个角度找到对象。表现光线反射到其他表面上,最终和不同的光源混合 在一起。使用一个伪元素添加两个渐变效果,让其看起来有两种光源结合在一起,如此一来可以创建一个更接近真实的球体。
.ball {
display: inline-block;
width: 100%;
height: 100%;
margin: 0;
border-radius: 50%;
position: relative;
background: radial-gradient(circle at 50% 120%, #81e8f6, #76deef 10%, #055194 80%, #062745 100%);
}
.ball:before {
content: "";
position: absolute;
top: 1%;
left: 5%;
width: 90%;
height: 90%;
border-radius: 50%;
background: radial-gradient(circle at 50% 0px, #ffffff, rgba(255, 255, 255, 0) 58%);
filter: blur(5px);
z-index: 2;
}
上面用了两个稍微复杂的渐变。
在ball
元素上用了一个渐变创建了一弱光的效果,渐变的中心定位在元素的(50% 120%)
位置。这样做,让结束的颜色不明显,渐变看起来过渡效果更流畅。
第二个渐变放在顶部,而且更亮,而且其大小是球体的90%
宽和高。渐变以圆心为中心,向下逐渐消失。
这里我们使用:before
创建阴影而不是使用一个新元素来创建。
自从渐变有锋利的边缘效果,我们曾使用blur
来软化这个锋利的边缘,不让它看上去那么突出。不幸的是,到目前为止,这个属性只有Webkit内核浏览器(Chrome和Safari)支持,但其他浏览器在未来也有可能会支持。
两个渐变效果组合之后,效果看起来更好:
Shinier
到目前为止,效果看起来很暗,让我们给效果添加一些光泽和创建一个斯诺克球。
为了实现这一目标,我们将利用柔和的光线,调整突出的顶部。我们需要利用两个伪元素来做这个效果。
.ball {
display: inline-block;
width: 100%;
height: 100%;
margin: 0;
border-radius: 50%;
position: relative;
background: radial-gradient(circle at 50% 120%, #323232, #0a0a0a 80%, #000000 100%);
}
.ball:before {
content: "";
position: absolute;
background: radial-gradient(circle at 50% 120%, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 70%);
border-radius: 50%;
bottom: 2.5%;
left: 5%;
opacity: 0.6;
height: 100%;
width: 90%;
filter: blur(5px);
z-index: 2;
}
.ball:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 5%;
left: 10%;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8) 14%, rgba(255, 255, 255, 0) 24%);
transform: translateX(-80px) translateY(-90px) skewX(-20deg);
filter: blur(10px);
}
这里在球体最初的颜色做了一个微秒的变化。同时在:before
伪类上写了一个更突出的效果,这个效果再次从球体的底部向球的表面反射光。
接下来添加了下新的伪类:after
,在这个伪类上使用一个从中心开始由白色过渡到透明(大约是在24%
的位置)的径向的渐变。这将创建了一个白色闪亮的效果,为了让它看上去更像一个反射的三维对像,我们在上面使用CSS的transform
。
使用transform
属性,将元素向左移80px
(translateX(-80px)
),并且向上移90px
(translateY(-90px)
),同时在X
轴扭转-20deg
(skewX(-20deg)
)。这样整个效果,看上去更像一个会发光的球体。
8号球
打斯诺克的同学,都知道最后要打一个8号球。下面我们额外增加一步,创建一个8号球。
我们需要额外添加一个元素,用来制作这个8
的效果:
<section class="stage">
<figure class="ball">
<span class="shadow"></span>
<span class="eight"></span>
</figure>
</section>
.ball .eight {
width: 110px;
height: 110px;
margin: 30%;
background: white;
border-radius: 50%;
transform: translateX(68px) translateY(-60px) skewX(15deg) skewY(2deg);
position: absolute;
}
.ball .eight:before {
content: "8";
display: block;
position: absolute;
text-align: center;
height: 80px;
width: 100px;
left: 50px;
margin-left: -40px;
top: 44px;
margin-top: -40px;
color: black;
font-family: Arial;
font-size: 90px;
line-height: 104px;
}
给这个新创建的元素添加一个border-radius:100%
样式,创建一个圆,而且将这个圆定位在球体的右上角位置,为了效果更贴切,给它加上一些transform
样式。为了让球体上能显示出8
这个数字,需要使用伪类:before
的content
,将其值设置为8
,然后运用一些CSS样式。最后其效果看起来如下:
添加眼睛
CSS除了有强大的transform
属性之外,还有animation
属性,可以制作一些动画效果。使用CSS的keyframe
,你可以给transform
添加一些动画效果。为了能更好的阐述这个,我们接下来创建一个会转动的眼睛。
第一步是在前面的8号球体示例的基础上调整一些颜色。让其看上去更像一个眼睛。修改后的HTML如下所示:
<section class="stage">
<figure class="ball">
<span class="shadow"></span>
<span class="iris"></span>
</figure>
</section>
大部分的CSS类似于制作8号,除一眼睛的膜和瞳孔部分。
.iris {
width: 40%;
height: 40%;
margin: 30%;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #208ab4 0%, #6fbfff 30%, #4381b2 100%);
transform: translateX(68px) translateY(-60px) skewX(15deg) skewY(2deg);
position: absolute;
animation: move-eye-skew 5s ease-out infinite;
}
.iris:before {
content: "";
display: block;
position: absolute;
width: 37.5%;
height: 37.5%;
border-radius: 50%;
top: 31.25%;
left: 31.25%;
background: black;
}
.iris:after {
content: "";
display: block;
position: absolute;
width: 31.25%;
height: 31.25%;
border-radius: 50%;
top: 18.75%;
left: 18.75%;
background: rgba(255, 255, 255, 0.2);
}
在iris
上创建一个蓝色的渐变,让其看上去像眼睛的膜,并且使用伪类来创建眼睛的瞳孔,使用样式让其更亮一点。并且给他们添加动画效果:
animation: animation-name 5s ease-out infinite;
在这个示例中,创建了一个名为animation-name
的动画,并且让动画持续5s
,而且是一直循环这个动画效果。为了让动画看上去更自然一些,给动画添加一个ease-out
函数,让动画由快到慢运动。
如果没有动画的话,我们创建的只是一个不会转动的眼睛,如下所示:
接下来通过keyframe
来创建眼球是如何运动。
@keyframes move-eye-skew {
0% {
transform: none;
}
20% {
transform: translateX(-68px) translateY(30px) skewX(15deg) skewY(-10deg) scale(0.95);
}
25%, 44% {
transform: none;
}
50%, 60% {
transform: translateX(68px) translateY(-40px) skewX(5deg) skewY(2deg) scaleX(0.95);
}
66%, 100% {
transform: none;
}
}
CSS的animation
中的keyframe
,初看起来很棘手。通过一系列的阶段来描述元素不同状态在做些什么。每个状态都通过百分比来控制。在这个示例中,主要通过其来改变iris
中的transform
。从20%
开始运用transform
,来移动睛球。而0%
到20%
之间的差距是由浏览器来控制的,其会自动计算,并且让这两个点达到平稳过渡。
继续在每个帧上控制transform
,正如前面指定的一样。而且让整个动画持续5s
。
为了能更好的兼容浏览器,别忘了创建keyfame
动画帧时,添加对应的浏览器前缀。
气泡
将box-shadow
和animation
结合在一起可以制作出各种各样有趣的效果,比如说气泡效果。
创建气泡效果看起来跟之前的球体类似,只是在用了更透明的颜色,并且在伪类上添加光泽效果。
同时在气泡上使用transform
,并且借助animation
让整个气泡摆动起来。
@keyframes bubble-anim {
0% {
transform: scale(1);
}
20% {
transform: scaleY(0.95) scaleX(1.05);
}
48% {
transform: scaleY(1.1) scaleX(0.9);
}
68% {
transform: scaleY(0.98) scaleX(1.02);
}
80% {
transform: scaleY(1.02) scaleX(0.98);
}
97%, 100% {
transform: scale(1);
}
}
动画运用在整个气泡上,其效果如下:
使用图像
到目前为止,我们看到的球体效果都没有使用任何图像。如果使用背景图像来制作球体效果需要添加更多的细节,而且还要利用伪元素的内阴影。如下面看到的示例。
添加一些渐变效果,并且添加一些光泽效果,让人产生一些错觉。
地球仪
动画也可以用来控制背景图的位置。这样一来我们可以创建一个旋转的地球仪效果。
比如我们拿一张世界地图的平面ltju来作背景:
为了能更好的创建一个3D空间,在效果上添加了一些阴影和动画。下面展示的效果是@@Sidoruk_SV写的一个旋转的地球仪:
总结
这篇文章通过示例一步一步的告诉大家如何使用CSS来创建3D球体效果。并且如何利用CSS的box-shadow
和渐变来给3D球体添加一些光泽效果,让球体更具像是在一个3D空间。并且配合CSS的animation
让整个球体运动起来。通过上面的示例再次证明了,运用好了box-shadow
和渐变能制作出各种各样的效果。如果你感兴趣的话,不仿自己动手也试试,说不定能整出更有意思的效果。同时也希望分享您制作的案例。
本文根据@Donovan的《Spheres》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处://cssanimation.rocks/spheres/。