使用CSS建立一個炫酷的球體動畫效果

我最近看到了一個純CSS實現的球體動畫效果:函數

圖片描述

通過研究上面的效果實現起來大體能夠分爲五個步驟,下面就來一一介紹。動畫

1.使用Jade和SCSS生成一個圓圈

建立一個圓圈的第一步是生成全部組成圓圈的粒子。有了Jade,咱們不用一個一個的寫出200個div。spa

如下的代碼建立了一個容器.mommy和200個div:3d

.mommy
  - for (var x = 0; x < 200; x++)
  div

添加一點CSS確認一下200個div已經生成:code

.mommy{
  border:1px solid black;
}
div{
  width: 4px;
  height: 4px;
  background:red;
}

正以下面你所看到的,咱們生成了一個800px高的紅色方塊,它是由200個div組成的。orm

clipboard.png

接下來,咱們要將這200個div分別定位在不一樣的位置組成一個圓圈,並經過SCSS來實現。blog

在上面的CSS中還須要再添加一些設置,給全部的div設置絕對定位,並將它們向左和向上移動2px的距離,這樣div的中心點與容器的0,0座標點就重合了。而後,咱們設置容器爲固定的寬高大小。圖片

.mommy{
  border:1px solid black;
  width: 400px;
  height: 400px;
  position: relative;
}
div{
  width: 4px;
  height: 4px;
  background:red;
  position: absolute;
  top: -2px;
  left: -2px;
}

經過SCSS,咱們能夠在for循環中爲每個div設置不一樣的位置,這樣就沒必要手動的一個一個去設置。首先建立一個變量,它的值等於div的個數,這樣在後面若是要用到div的數量值時,直接引用這個變量就能夠了。若是有一天須要改變成400個div,只須要在CSS中改變變量的值就能夠了。ip

$amount : 200;
@for $i from 1 through $amount {
  //循環中的代碼
}

如今咱們就能夠在循環中改變每一個div的座標了,這須要一點點的數學計算。animation

如下的函數就是生成圓圈的座標點的計算公式:

x = cos((index/amount)*(PI*2))*radius + radius;
y = sin((index/amount)*(PI*2))*radius + radius;

用SCSS來表示上面的公式就是:

$x : cos(($i/$amount)*360deg)*200px + 200;
$y : sin(($i/$amount)*360deg)*200px + 200;

而後咱們將經過公式計算得出的點座標應用在每一個div上:

div:nth-child(#{$i}){
    transform: translate3d($x, $y,0px);
}

這是第一步生成的結果,雖然不是很漂亮,可是,嗯,你從零開始創造了一個圓圈!

clipboard.png

2.將圓圈變成一個球體

如今咱們有了一個用SCSS生成的圓圈,可是咱們須要的是一個球體。圓圈是一個二維圖形,而球體是一個三維立體圖形。二維幾何圖形只有兩個軸:X軸和Y軸,而對於三維,又多了一個座標軸:Z軸。這意味着咱們還要計算每一個div在Z軸上的位置座標。幸運的是,已經有成熟的公式幫助咱們來定位球體上每一個元素的位置,我不會詳細的介紹公式的原理(屬於數學範疇),咱們只須要使用就能夠了:

θ : (index / amount) * 120;
δ : (index / amount) * PI;
x : radius * cos(δ) * cos(θ);
y : radius * cos(δ) * sin(θ);
z : radius * sin(δ);

如今咱們有了以上的函數,它能夠徹底知足咱們的需求,咱們把它插入到循環中。

@for $i from 1 through $amount {
  $theta : ($i / $amount) * 120;
  $delta : ($i / $amount) * pi();
  $x : 200px * cos($delta) * cos($theta) + 200; //+200 to center our sphere in our 3D world
  $y : 200px * cos($delta) * sin($theta) + 200; //+200 to center our sphere in our 3D world
  $z : 200px * sin($delta);
  div:nth-child(#{$i}){
    transform: translate3d($x, $y,$z);
  }
}

下面就是生成的球體效果,正如你所看到的,全部的div都有從新有了新的位置,可是咱們看到的好像仍然是平面效果,不是3D立體的。

clipboard.png

在CSS中有一個叫perspective的屬性,它容許咱們爲任何元素設置一個特定的透視值。在咱們的例子中,咱們但願在容器.mommy設置3D效果。而且還須要設置一個transform-style: preserve-3d;這樣全部的div就處於立體座標系中了。

clipboard.png

如今咱們能夠看到全部div的大小都變得不同了。div距離「屏幕」的距離越遠,它就會越小,這意味着它們已經處於立體座標系中了!

3.旋轉球體

全部的div已經就緒了,接下來咱們就要看到最後的結果了。咱們設置一個僅有一個關鍵幀的動畫效果:

.mommy{
  [...]
  animation: rotation 10s linear infinite; 
}
@keyframes rotation{
  to{
    transform:rotateY(360deg);
  }
}

圖片描述

你可能已經注意到,有些div不是正面屏幕而是與屏幕成90°時,它們就會消失看不到。爲了防止這種狀況的發生,咱們須要給每一個div一個反方向的旋轉,讓它們的正面始終面對屏幕顯示。

咱們要在div上應用一個反方向的旋轉,可是因爲已經應用了一個轉換,咱們將利用僞元素,它將成爲紅色的小方塊。這樣,div自己只須要提供定位做用就能夠了,而且設置一個transform-style屬性,讓div處於3D環境中。

div{
  [...]
  transform-style: preserve-3d;
  &:before{
    content:"";
    display: block;
    width: 4px;
    height:4px;
    background:red;
    animation: rotation 10s infinite linear reverse; 
  }
}

圖片描述

塔達!CSS球體的效果就這樣作好了!

4.更炫的球體

在以上代碼的基礎上,咱們發散思惟,能夠作出更加炫酷的球體效果:

圖片描述
圖片描述

獲取以上全部球體動畫的代碼能夠:

圖片描述

相關文章
相關標籤/搜索