CSS中如何實現僞隨機?

今天看《CSS揭祕》,學到了一個有趣的知識點:怎麼實現僞隨機?css

以爲既有趣,又有啓發,這裏記錄分享一下。web

問你個問題,什麼叫隨機呢? wordpress

咱們能夠從相反的角度來思考,先回答什麼叫不隨機。動畫

不隨機就是有必定規律可循,好比下圖中的顏色出現就是有規律的:spa

從圖上能夠看出紅綠藍這三種顏色,每隔六次就總體重複一遍。3d

上圖是我使用 CSS 實現並截圖的。這裏仔細看一下源碼:code

div:nth-child(n){
  background: red;
}
div:nth-child(2n+1){
  background: green;
}
div:nth-child(3n+2){
  background: blue;
}
複製代碼

由於 一、二、3的最小公倍數是 6,因此顏色分佈規律的週期是 6。cdn

這裏要強調的咱們說的顏色總體分佈規律,是不考慮 CSS 層疊機制帶來的影響。blog

好比以下的代碼:生命週期

div:nth-child(2n){
  background: red;
}
div:nth-child(n){
  background: green;
}
div:nth-child(3n+1){
  background: blue;
}
複製代碼

產生以下的顏色分佈:

但咱們仍然能夠說它的週期是 6,哪怕這裏很特殊,其最小週期是 3。

原理

如何讓顏色分佈不太有規律呢?

不太有規律,就是隨機的概念。

也就是說,你看着圖像,卻一時半會找不到有啥規律。

若是隻限定這三種顏色(這個前提很重要),一個可行辦法是讓最小公倍數大一些,好比說 35。

由於咱們目前的 div 總共才 24 個。而總體重複週期爲 35 的話,那麼這 24 個顏色其效果必然就很像隨機了。固然也只是「像」而已,因此是僞隨機。

35 的因子是 五、7。其中 5 和 7 都是素數。

素數是很好的選擇,由於是素數的整數倍,好比 5n 和 7n 在 35 以內基本沒有衝突的。

同時 5n+a 與 7n+b 發生衝突的次數也會盡量的少。進而若是 a 與 b 也都是素數的話,衝突會更少。好比 5n+3 與 7n+5 只有在 33 處衝突。

好比這種顏色分佈:

其代碼是:

div:nth-child(n){
  background: red;
}
div:nth-child(5n+1){
  background: green;
}
div:nth-child(7n+4)
{
  background: blue;
}
複製代碼

固然,上述效果中,默認顏色紅色太多。主要緣由是每種顏色的週期內,咱們只應用了一次。這裏能夠相應增長頻次:

div:nth-child(n){
  background: red;
}
div:nth-child(5n+1),
div:nth-child(5n+4){
  background: green;
}
div:nth-child(7n+4),
div:nth-child(7n+6)
{
  background: blue;
}
複製代碼

產生的效果以下:

以上效果是限定在 3 種顏色以內的隨機方案。

若是容許增長其餘的顏色的話,這裏咱們能夠增長其餘素數因子便可。

應用

這種僞隨機還有其餘應用嗎?

《CSS揭祕》中有兩個例子。

1.僞隨機背景

css 中可使用線性漸變實現條紋,好比:

background: repeating-linear-gradient(90deg, 
  red, red 15px, 
  green 0, green 30px, 
  blue 0, blue 45px);
複製代碼

效果是:

也可使用多重背景來實現:

background:
  linear-gradient(90deg, red 15px, transparent 0),
  linear-gradient(90deg, green 30px, transparent 0),
  linear-gradient(90deg, blue 45px, transparent 0);
background-size: 45px 100%;
複製代碼

接下來咱們讓顏色出現隨機些,設置背景大小爲素數版的:

background-size: 41px 100%, 61px 100%, 83px 100%;
複製代碼

效果以下,其中默認背景顏色是白色。

同時也可進一步設置顏色寬度:

background:
  linear-gradient(90deg, red 11px, transparent 0),
  linear-gradient(90deg, green 23px, transparent 0),
  linear-gradient(90deg, blue 41px, transparent 0);
background-size: 41px 100%, 61px 100%, 83px 100%;
複製代碼

具體請看其在線例子

2 動畫組合

咱們知道動畫屬性 animation 與 background 屬性同樣,也支持多套值。

而在同一個元素上應用多套動畫,咱們也可以讓其總體週期更大些,進而每一幀的狀態都是隨機的組合。

好比:

animation: 1s spin, .7s radius, 1.1s color, 1.3s width;
複製代碼

具體請看其在線例子

蟬原則

經過素數增長隨機性的這種方法,書中管它叫蟬原則。

百度了一下,張鑫旭老師也介紹了:《「蟬原則」與CSS3隨機多背景隨機圓角等效果》

大致說來,之因此叫「蟬」原則,是由於人家蟬的生命週期(主要仍是爆發週期)是那種 13 或 17年的。週期又大,又是素數。這樣就能與其天敵的週期儘量相避開(週期是一年的話,就無法避開了?)。

最後列一下其餘有用的資料。

相關文章
相關標籤/搜索