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年的。周期又大,又是素数。这样就能与其天敌的周期尽量相避开(周期是一年的话,就无法避开了?)。

最后列一下其余有用的资料。