1. 程式人生 > >[譯] 使用CSS製作球體

[譯] 使用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標籤,而它被的父元素是stagediv。當我們想要設定perspective和定位陰影時, 父元素stagediv很有用,因為可以看起來更像是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示例中是包含的。在上面示例中我給stagediv設定perspective: 1200pxperspective屬性使具有三維位置變換的元素產生透視效果[大概意思應該是這個]。

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-outease-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中的動畫關鍵幀剛開始用起來可能會比較難,你正在做的是用一系列場景來展示元素的各個狀態,每個狀態對應一個百分比。在該示例中,iristransform: 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著色。

hop.ie/balls/image…

新增些css漸變效果可以達到深度錯覺。

See the Pen Spheres tutorial: 7 Tennis ball by Donovan Hutchinson (@donovanh) on CodePen.

Around the world

動畫可以應用於背景影象的位置,使用它我們可以實現旋轉地球儀效果。

下面的平面圖像在頂部和底部位置稍做拉伸用來作為背景影象。

hop.ie/balls/image…

通過新增陰影和動畫,可以創建出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和團隊提供的出色資源。

如果您對上述內容有任何疑問,請通過電子郵件Twitter與我們聯絡。