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%就能制作一个圆。当然,其前提是元素的widthheight是相同(即是一个正方形)。

.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效果,转换阴影位置。你可以使用rotatescaletranslate或者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这个数字,需要使用伪类:beforecontent,将其值设置为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-shadowanimation结合在一起可以制作出各种各样有趣的效果,比如说气泡效果。

创建气泡效果看起来跟之前的球体类似,只是在用了更透明的颜色,并且在伪类上添加光泽效果。

同时在气泡上使用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);
  }
}

动画运用在整个气泡上,其效果如下:

使用图像

到目前为止,我们看到的球体效果都没有使用任何图像。如果使用背景图像来制作球体效果需要添加更多的细节,而且还要利用伪元素的内阴影。如下面看到的示例。

3D球体

添加一些渐变效果,并且添加一些光泽效果,让人产生一些错觉。

地球仪

动画也可以用来控制背景图的位置。这样一来我们可以创建一个旋转的地球仪效果。

比如我们拿一张世界地图的平面ltju来作背景:

地球仪

为了能更好的创建一个3D空间,在效果上添加了一些阴影和动画。下面展示的效果是@@Sidoruk_SV写的一个旋转的地球仪:

总结

这篇文章通过示例一步一步的告诉大家如何使用CSS来创建3D球体效果。并且如何利用CSS的box-shadow和渐变来给3D球体添加一些光泽效果,让球体更具像是在一个3D空间。并且配合CSS的animation让整个球体运动起来。通过上面的示例再次证明了,运用好了box-shadow和渐变能制作出各种各样的效果。如果你感兴趣的话,不仿自己动手也试试,说不定能整出更有意思的效果。同时也希望分享您制作的案例。

本文根据@Donovan的《Spheres》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处://cssanimation.rocks/spheres/