今天看《CSS揭祕》,學到了一個有趣的知識點:怎麼實現偽隨機?
覺得既有趣,又有啟發,這裡分享記錄分享一下。
問你個問題,什麼叫隨機呢?
我們可以從反面來回答,什麼叫不隨機呢?
不隨機就是有一定規律可循,比如下圖中的顏色出現就是有規律的:
從圖上可以看出紅綠藍這三種顏色,每隔六次就整體重複一遍。
上圖我使用 CSS 實現並截圖的。這裡仔細看一下原始碼:
div:nth-child(n){
background: red;
}
div:nth-child(2n+1){
background: green;
}
div:nth-child(3n+2){
background: blue;
}
複製程式碼
因為 1、2、3的最小公倍數是 6,所以顏色分佈規律的週期是 6。
這裡要強調的我們說的顏色整體分佈規律。
比如如下的程式碼:
div:nth-child(2n){
background: red;
}
div:nth-child(n+1){
background: green;
}
div:nth-child(3n+1){
background: blue;
}
複製程式碼
產生如下的顏色分佈:
但我們仍然可以說它的週期是 6,哪怕這裡很特殊,其最小週期是 3。
原理
如何讓顏色分佈不太隨機呢?
不太隨機,就是偽隨機的概念。即,你看著影象,一時半會找不到規律。
如果只限定這三種顏色(這個前提很重要),一個可行辦法是讓最小公倍數大一些。比如說 35。因為我們目前的 div 總共才 24 個。而整體重複週期為 35 的話,那麼這 24 個顏色其效果必然就很像隨機了。
35 的因子是 1、5、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年的。週期又大,又是素數。這樣就能與其天敵的週期儘可能相避開。
最後列一下其他有用的資料。