CSS揭秘——伪随机背景

·  阅读 25

重复平铺很有美感,但有时我们希望实现随机性的展示,因为自然界中的事物都不是以无限平铺的方式存在。就像没有两朵花是完全一样的,所以我们会试图让背景图案尽可能显得自然。

因为 CSS 本身没有提供任何随机功能,因此想实现这种随机性是一个很大的挑战。先从一个简单的条纹实现开始,创建一个具有四种颜色的条纹图案(为方便,这里以四种颜色为例):

epub_26211795_127.jfif

background: linear-gradient(90deg, #fb3 15%, #655 0, #655 40%, 
                #ab4 0, #ab4 65%, hsl(20, 40%, 90%) 0);
background-size: 80px 100%;
复制代码

可以看到,这个规律就非常明显,渐变图案每隔 80px 就会重复一次。

为了更真实地模拟条纹的随机性,可以把这组条纹从一个平面拆分成多个图层:一种颜色做底色,另三种颜色作为条纹,然后以不同的间隔进行重复平铺。可以在色标中定好条纹宽度,再用 background-size 来控制条纹的间距:

epub_26211795_128.jfif

background: hsl(20, 40%, 90%) 0);
background-image:   linear-gradient(90deg, #fb3 10px, transparent 0), 
                    linear-gradient(90deg, #ab4 20px, transparent 0), 
                    linear-gradient(90deg, #655 20px, transparent 0);
background-size: 80px 100%, 60px 100%, 40px 100%;
复制代码

最顶层贴片的重复规律是很容易被察觉,因此应该把平铺间距最大的贴片安排在最顶层,在这个例子中就是 #fb3 这个颜色。 ps:这里的贴片指的不仅仅是渐变图案中的重复单元,还指多层渐变合成的最终图案中可感知的重复单元。

可以看到这样的效果已经很有随机的感觉,但如果仔细看,可以发现图案是每隔 240px 就会重复一次。这个组合第一个贴片的终点,就是各层背景图像以不同间距重复数次后再次统一对齐的点。简单来说,这个贴片的尺寸就是 background-size 中设置的三个间距的最小公倍数,80、60、40 的最小公倍数就是 240。

如果想让随机性更加真实,需要把贴片的尺寸最大化,也就是这个最小公倍数也尽量最大化(最大公约数最好为 1 ),那就需要选择互质的数字,因为质数跟其他任意数字(非自己倍数的数字)都是互质的。

现在来用质数来指定各组条纹宽度:

epub_26211795_130.jfif

background: hsl(20, 40%, 90%) 0);
background-image:   linear-gradient(90deg, #fb3 10px, transparent 0), 
                    linear-gradient(90deg, #ab4 20px, transparent 0), 
                    linear-gradient(90deg, #655 20px, transparent 0);
background-size: 41px 100%, 61px 100%, 83px 100%;
复制代码

这个时候一个贴片的尺寸是 41 * 61 * 83 = 207583 像素,不会有比这个还大的屏幕分辨率了吧。

这个技巧被 Alex Walker 定名为 ”蝉原则“,是他最先提出的通过质数来增加随机真实性的想法。这个方法也不仅适用于背景,还可以用于其他有关规律重复的情况。

  • 在照片图库中,为每幅图片应用细微的伪随机旋转效果时,可以使用多个 :nth-child(a) 选择符,让 a 为质数。
  • 若生成一个动画,想让它不是按照明显规律循环时,可以用多个时长为质数的动画。

浙江大华技术股份有限公司-软研-智慧城市产品研发部招聘高级前端!!!!! 欢迎大家来聊,有意向可发送简历到 chen_zhen@dahuatech.com,加入我们,可以一起进步,一起聚餐,一起旅游,让我们从世界村的小伙伴变成大华村的小伙伴。

分类:
前端
标签: