原文链接:cssanimation.rocks/spheres/
使用border-radius
属性,我们可以实现带圆角的形状和圆形。可以添加一些渐变效果来使他们变成圆球。让我们尝试一下,并且可以添加一些动画效果来赋予他们活力。
平面设计
我们可以通过两种方式用css来制作圆球。
第一种方式是通过使用大量元素来创建一个真正的3D球体。这种方式存在的缺点就是需要浏览器渲染许多元素,从而可能会影响性能。由于一个平滑的球体需要用到很多元素,所以看起来有点粗糙[应该是想表达想画一个平滑球体,需要特别多的元素来填补,不然看起来不光滑?]
相反地我会尝试第二种方式,利用css渐变来添加阴影,以及在一个单元素上添加3D效果。
例子和源码
所有在文章中提到的例子可以通过我的codepen账户找到,或者在文章中每个事例中选择“Edit on Codepen”查看源码。
在代码示例中,我没有添加任何浏览器前缀[css前缀]。我推荐使用像Autoprefixer这样的给工具,或者根据自己的需要添加相应的前缀。
基本形状
在添加细节前,我们先创建一个最基本的圆形。
从HTML开始:
<figure class="circle"></figure>
复制代码
这里我们使用figure
元素,但你也可以使用其他元素。figure
是HTML5中用于表示图像或图表的元素,它是内容的一部分,可以在不影响内容含义的情况下删除。
通过figure
元素来创建一个圆,我会给它设置宽高,并且设置border-radius
为50%。任何形状只要设置border-radius
超过50%,都会变成圆形。
.circle {
display: block;
background: black;
border-radius: 50%;
height: 300px;
width: 300px;
margin: 0;
}
复制代码
一个圆形的展示。
See the Pen Spheres tutorial: 1. Circle by Donovan Hutchinson ( @donovanh) on CodePen.现在我们有了一个最基础的圆形,我们可以开始美化它,让它看起来更像个球形。
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);
}
复制代码
你应该可以看到像这样的效果:
See the Pen Spheres tutorial: 1.b Circle + basic shading by Donovan Hutchinson (@donovanh) on CodePen.
径向渐变
radial-gradient
属性需要配置一些参数。第一个参数是渐变开始的中心位置。根据*shape* at *position*
这种格式。在上个例子中,渐变形状是circle
,它的中心位置离左侧100px,离顶部100px。
接下来是设置一系列颜色。你可以指定两种颜色以上,但必须在每个颜色之间添加一个距离,可以让渐变知道何时将每个颜色过渡到它的下个颜色。
在这个例子中指定了两种颜色,这让浏览器默认第一个颜色从0%开始,第二个颜色为100%结束,在这两个颜色间绘制过渡效果。假如我们想改变渐变中的其他步骤,可以指定距离,用像素或者百分比来表示,在接下来的描述中可以看到。
我们有一个看起来有点像3D的东西,看起来很棒,但让我们尝试着让它看起来更好一些。
Shadows & 3D
根据你应用于曲面的着色阴影,可以创建出不同的外观效果。首先,让我们设置一个场景来将球放在里面。
在这里我们将用到更多的HTML元素:
<section class="stage">
<figure class="ball"><span class="shadow"></span></figure>
</section>
复制代码
类名为ball
的标签里面包含了用来创建阴影效果span
标签,而它被的父元素是stage
div。当我们想要设置perspective
和定位阴影时, 父元素stage
div很有用,因为可以看起来更像是3D效果。
给stage
以及shadow
添加样式。
.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;
}
复制代码
注意,在上面示例中我没有添加相对于的css前缀,但在codepen示例中是包含的。在上面示例中我给stage
div设置perspective: 1200px
,perspective
属性使具有三维位置变换的元素产生透视效果[大概意思应该是这个]。
给shadow
设置径向渐变radial gradient
,然后使用transform
属性来对其定位。在3D空间里,transform
属性包括旋转[rorate]、缩放[scale]、移动[move]和倾斜[skew]。让shadow
在x轴上旋转90度,z轴上向下偏移150px。
由于我们在stage
容器设置了perspective
属性,所以shadow
看起来像是一个拉伸的椭圆形,感觉像圆球的影子。
See the Pen Spheres tutorial: 2 Basic plus shadow by Donovan Hutchinson (@donovanh) on CodePen.
它现在看起来比之前要好一点了,让我们为它添加更多的底纹效果。
Multiple shaders
现实中很少会看到只有一个角度发光的物体,因为光会反射到其他表面上,最终各种光源混合在一起。为了让这个球看起来更加真实,我们使用伪元素添加两个渐变,让它看起来更有光泽。
.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
效果去对其进行柔化,但目前该属性只有chrome和safari支持,但在未来其他浏览器中,它可能会发挥更大的作用。
以上两个渐变的设置让球拥有更好的视觉效果:
See the Pen Spheres tutorial: 3 Better shading by Donovan Hutchinson (@donovanh) on CodePen.
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
,它是一个圆形渐变效果,从中心位置50% 50%
渐变,并在24%左右的标记处渐变为透明。这个渐变产生了白色反光的效果,但为了让它看起来更像是一个反射光,我们设置了transform
来调整它的位置。
设置transform
属性,往左移动80px,往上移动90px,并且设置了倾斜效果,往x轴倾斜拉伸,使其看起来更像是球反射出的光泽。
See the Pen Spheres tutorial: 4 Shinier by Donovan Hutchinson (@donovanh) on CodePen.
8-ball
让我们继续添加数字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
创建圆eight
,并设置transdform
属性将该元素定位在右上角。这里我使用before
伪元素将数字8添加到content
,然后以类似的方式来调整该数字的位置。
一个带光泽的8号台球。
See the Pen Spheres tutorial: 4.b 8-ball by Donovan Hutchinson (@donovanh) on CodePen.
Got my eye on you
css的transform
的一大优点就是可以被应用在动画上面,将csskeyframes
关键帧用于动画,可以将一系列元素变换作为动画应用在元素上。我将制作一个会动的眼球。
首先是调整示例8-ball中使用的一些颜色,细微的调整让它看起来更像是个眼睛。HTML代码:
<section class="stage">
<figure class="ball">
<span class="shadow"></span>
<span class="iris"></span>
</figure>
</section>
复制代码
除了虹膜和瞳孔样式之外,其他css样式大部分类似于示例8-ball。
.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);
}
复制代码
蓝色渐变形成虹膜的彩色部分,而瞳孔和高光效果使用伪元素进行创建,我还将动画属性animation
应用到iris
元素,设置如下:
animation: animation-name 5s ease-out infinite;
复制代码
在该例子中,设置了一个名为“animation-name”的动画,时间设置为5秒,无限循环,并设置其缓动效果为ease-out
。ease-out
指动画在快结束时速度变慢,从而达到更加自然的效果。
在没有创建动画情况下,我们看到一个不会动的眼球。
See the Pen Spheres tutorial: 5 Eyeball by Donovan Hutchinson (@donovanh) on CodePen.
让我们创建关键帧keyframes
来描述眼球应该如何移动。
@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中的动画关键帧刚开始用起来可能会比较难,你正在做的是用一系列场景来展示元素的各个状态,每个状态对应一个百分比。在该示例中,iris
从transform: none
开始,在20%时,它设置了iris
向左移动倾斜。浏览器会自动计算0~20%之间的差距,从而在两者之间进行平滑的过渡。
就像前面说的,完成关键帧中设置的一系列场景需要5秒。
不要忘记设置样式需要的前缀,因为有些浏览器存在兼容css样式问题。
See the Pen Spheres tutorial: 5b Eyeball (animated) by Donovan Hutchinson (@donovanh) on CodePen.
Bubbles
动画和颜色渐变可以产生各种有趣多变的效果,比如气泡?
创建气泡的外观与前面的例子类似,在主色调中将透明度调高,并使用俩个伪元素来增加光泽。
设置动画使气泡动起来。
@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);
}
}
复制代码
动画适用于整个气泡以及伪元素。
See the Pen Spheres tutorial: 6 Bubble (animated) by Donovan Hutchinson (@donovanh) on CodePen.
Using images
到目前为止,所有球都是在不使用任何图像的情况下创建的。背景图像可以添加更多的细节,并且仍然可以利用伪元素中的css着色。
添加些css渐变效果可以达到深度错觉。
See the Pen Spheres tutorial: 7 Tennis ball by Donovan Hutchinson (@donovanh) on CodePen.
Around the world
动画可以应用于背景图像的位置,使用它我们可以实现旋转地球仪效果。
下面的平面图像在顶部和底部位置稍做拉伸用来作为背景图像。
通过添加阴影和动画,可以创建出3D效果的地球仪,可以在Codepen查看其运行结果。由于该示例的性能问题,我这里设置为默认显示HTML。
ps: 非常感谢Sidoruk Sergey(@Sidoruk_SV)优化这个示例,看起来很棒。
See the Pen Globe by Donovan Hutchinson (@donovanh) on CodePen.
Resources
如果你想了解更多信息,请参考一些有关radial gradients
的资料。
想要找更多3D例子?查看Portal CSS获取更多。
Feedback
所有的示例都可以在我的codepen找到。非常感谢Chris和团队提供的出色资源。