css画背景图:paint

 我们开发中使用的背景图大部分是(png, webp等)图片svg矢量图canvas画图, 但是其实我们也可以选择css直接画图, 那css这种甚至都”称不上”编程语言的家伙怎么绘制复杂的图片那?

image.png

1: 为元素赋予css属性
1
<div class="box"></div>
1
2
3
4
5
6
<style> .box {
width: 180px;
height: 180px;
border: 1px solid;
background: paint(xxxx); // 主角在此
}

    paint(xxxx); 这里填入的是绘图的”方法名”, 往下看就知道啥是”方法名”了, 之所以我这里写”xxxx”非常随意, 是因为我想表达这个名字随便起。

2: 引入js文件
1
2
3
4
<script> if (window.CSS) {
// 因为加载文件 需要启动server
CSS.paintWorklet.addModule("./paint-grid.js");
} </script>

    用法有点诡异, 但核心其实是引入了一个js文件

3: js文件内定义导出的方法

    paint-grid.js文件:

1
2
3
4
5
6
7
8
9
registerPaint(
"xxxx", // 这就是: 方法名
class {
paint(context, size) {
context.fillStyle = 'red';
context.fillRect(10, 10, 39, 39);
}
}
);

    paint方法里面就类似canvas了, 可以正常使用部分js代码。

    当前的效果展示:

4: 可多导出

    当看到需要指定绘制的”方法名”而不是”文件名”, 我就知道他一定可以导出多个喽:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
registerPaint(
"xxxx1",
class {
paint(context, size) {
context.fillStyle = 'red';
context.fillRect(10, 10, 39, 39);
}
}
);

registerPaint(
"xxxx2",
class {
paint(context, size) {
context.fillStyle = 'green';
context.fillRect(10, 10, 39, 39);
}
}
);

两个元素的样式设置

1
2
3
4
5
6
7
<style> .box {
background: paint(xxxx1);
}
.box2 {
margin-top: 20px;
background: paint(xxxx2);
}

5: 变量赋予背景灵动

    我们时长遇到需要绘制”非固定大小背影”, 此时在paint-grid.jswindow是获取不到的, 但是我们可以使用css变量:

1
2
3
4
// 在全局定义方便js修改
:root {
--bg-size: 60;
}

    paint-grid.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
registerPaint(
"xxxx1",
class {
static get inputProperties() {
return ["--bg-size"];
}
paint(context, size, properties) {
var bgSize = properties.get('--bg-size');
context.fillStyle = "red";
context.fillRect(10, 10, bgSize, bgSize);
}
}
);

    inputProperties定义了需要获取哪些属性, paint的第三个参数可以接收这些属性, 这样瞬间就感觉这个属性还有点用啦。

6: 注意事项
  1. 不能在js文件的绘制方法里面写alert, 会导致报错阻断绘制:

  2. 要注意维护 paint-grid.js文件与css文件的相关性, 因为大家写代码会下意识的不会认为js方法被css文件里的属性所使用, 这就导致可能后续无删除或者是不敢删除等问题。

  3. 适合处理简单的图形, 如果复杂度高了或者还需借助其他”库”的情况, 则不建议使用。