最近打算花一点时间,写一个系列,给大家介绍一些有趣的开源项目的基本原理,这算是第一篇文章。
今天要介绍的是袁川大佬的css-doodle项目,这是一个持续更新多年的优秀开源项目。早在2019年的css-conf上,我就有幸听过袁川老师介绍这个项目,当时就感觉挺惊艳的,没想到CSS可以做这样的事情。更难能可贵的是,这个项目这几年一直持续更新,增加了越来越多有趣的特性,还支持了WebGL。
这个项目到底是怎样?为什么说它非常惊艳,我们先通过几个例子来直观感受一下吧。
我们可以看到,这些有趣的图案和动画,本身是通过类似于写自定义元素css-doodle
内的CSS样式规则来实现。
它的具体使用并不复杂,上手十分简单,只要你理解CSS样式,就能很容易写出基本规则。
首先是使用@grid
属性来定义网格,网格是 M x N
的方格,css-doodle最小支持 1x1
最大支持 256x256
的网格。
<css-doodle>
<style>
background: #60569e;
@grid: 5,5 / 8em, 8em;
:doodle {
grid-gap: 1px;
}
</style>
</css-doodle>
以上规则定义了一个5X5
的网格,容器最大的宽、高是8em
。绘制出来的效果如下:
如果只是绘制网格,还是不能实现前面的那些效果,实际上css-doodle提供了一系列选择器、内置变量与函数。
我们先尝试修改一下上面的代码:
演示地址👉🏻 https://code.juejin.cn/pen/7094069339829043207
<css-doodle>
<style>
background: #60569e;
@grid: 5,5 / 12em, 12em;
:doodle {
grid-gap: 1px;
}
:after {
content: @index;
// content: @row @col;
color: white;
}
</style>
</css-doodle>
@index
变量定义了网格的索引,@row @col
定义了行列,你可以把上面代码中的注释去掉看看结果。
我们还可以把 @row、@col
作为函数选择器使用,在上面的代码里添加:
@row(3) {
background: red;
}
@col(3) {
background: red;
}
这样我们就可以把第三行、第三列选择出来:
我们还可以通过@at
函数选择指定行列,比如:
@at(4, 4) {
background: orange;
}
此外,css-doodle支持更加复杂的@match
规则,例如:
@match(@row > @col) {
background: red;
}
@match(@row = @col) {
background: orange;
}
随机与重复
我们通过@rand
方法可以生成随机数,比如:
background: hsl(@rand(0, 360), 50%, 50%);
transform: rotate(@rand(0, 90)deg) scale(@rand(50, 90)%);
@pick、@pick-n、@pick-d
等方法可以随机或者顺序选取其中的值。
// background: @p(red,orange,blue,gray);
// background: @pn(red,orange,blue,gray);
background: @pd(red,orange,blue,gray);
除了这些以外,还可以用 @random
(区别 @rand) 作为选择器使用,比如下面的代码选出网格中20%的元素:
@random(.2) {
background: black;
}
有了随机的能力,我们就可以来做一些更有趣的事情了,比如下面这个例子:
噪声
除了@rand
函数,css-doodle还有一个类似的@rn
函数,它是噪声函数。
我们把前面例子的@rand
换成@rn
试一下:
background: hsl(@rn(0, 360), 50%, 50%);
transform: rotate(@rn(0, 90)deg) scale(@rn(50, 90)%);
通俗来说,噪声是平滑后的随机,我们换一个例子来更直观地看一下:
随机与噪声都非常有用,尤其是在WebGL的效果里面,恰好,现在css-doodle支持了shader,这样我们就可以把随机和噪声的输出作为texture用于webgl渲染。
Shader
因为是WebGL的部分,和CSS有些不同,在这里暂不打算细讲,先放两个例子,有兴趣的同学可以去研究,恰好最近还要介绍另外一个doodle
,即glsl-doodle,等到那时,我们再来详细讨论shader和WebGL的问题吧。