css-doodle:如何让CSS成为艺术?

avatar
掘金前首席打杂官

最近打算花一点时间,写一个系列,给大家介绍一些有趣的开源项目的基本原理,这算是第一篇文章。

今天要介绍的是袁川大佬的css-doodle项目,这是一个持续更新多年的优秀开源项目。早在2019年的css-conf上,我就有幸听过袁川老师介绍这个项目,当时就感觉挺惊艳的,没想到CSS可以做这样的事情。更难能可贵的是,这个项目这几年一直持续更新,增加了越来越多有趣的特性,还支持了WebGL。

这个项目到底是怎样?为什么说它非常惊艳,我们先通过几个例子来直观感受一下吧。

code.juejin.cn/pen/7094068…

code.juejin.cn/pen/7091492…

code.juejin.cn/pen/7091564…

我们可以看到,这些有趣的图案和动画,本身是通过类似于写自定义元素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。绘制出来的效果如下:

1651717772270.jpg

如果只是绘制网格,还是不能实现前面的那些效果,实际上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>

1651718427453.jpg

@index变量定义了网格的索引,@row @col定义了行列,你可以把上面代码中的注释去掉看看结果。

我们还可以把 @row、@col 作为函数选择器使用,在上面的代码里添加:

@row(3) {
  background: red;
}
@col(3) {
  background: red;
}

这样我们就可以把第三行、第三列选择出来:

1651719268512.jpg

我们还可以通过@at函数选择指定行列,比如:

@at(4, 4) {
  background: orange;
}

此外,css-doodle支持更加复杂的@match规则,例如:

@match(@row > @col) {
  background: red;
}
@match(@row = @col) {
  background: orange;
}

1651719680924.jpg

随机与重复

我们通过@rand方法可以生成随机数,比如:

background: hsl(@rand(0, 360), 50%, 50%);
transform: rotate(@rand(0, 90)deg) scale(@rand(50, 90)%);

1651720537470.jpg

@pick、@pick-n、@pick-d等方法可以随机或者顺序选取其中的值。

// background: @p(red,orange,blue,gray);
// background: @pn(red,orange,blue,gray);
background: @pd(red,orange,blue,gray);

1651721285179.jpg

除了这些以外,还可以用 @random (区别 @rand) 作为选择器使用,比如下面的代码选出网格中20%的元素:

@random(.2) {
  background: black;
}

1651721589614.jpg

有了随机的能力,我们就可以来做一些更有趣的事情了,比如下面这个例子:

code.juejin.cn/pen/7091538…

噪声

除了@rand函数,css-doodle还有一个类似的@rn函数,它是噪声函数。

我们把前面例子的@rand换成@rn试一下:

background: hsl(@rn(0, 360), 50%, 50%);
transform: rotate(@rn(0, 90)deg) scale(@rn(50, 90)%);

1651722058044.jpg

通俗来说,噪声是平滑后的随机,我们换一个例子来更直观地看一下:

code.juejin.cn/pen/7094092…

随机与噪声都非常有用,尤其是在WebGL的效果里面,恰好,现在css-doodle支持了shader,这样我们就可以把随机和噪声的输出作为texture用于webgl渲染。

Shader

因为是WebGL的部分,和CSS有些不同,在这里暂不打算细讲,先放两个例子,有兴趣的同学可以去研究,恰好最近还要介绍另外一个doodle,即glsl-doodle,等到那时,我们再来详细讨论shader和WebGL的问题吧。

例子一

例子二