[譯] 使用CSS製作球體
原文連結: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和團隊提供的出色資源。