CSS Painting API - 允许开发人员编写 JavaScript 函数,直接绘制到元素的背景,边框或内容中

CSS Painting API(CSS 绘画 API)(是 CSS Houdini API 的一部分),允许开发人员编写 JavaScript 函数,这些函数可以直接绘制到元素的背景,边框或内容中。

概念和用法

基本上,CSS 绘画 API 包含的功能允许开发者为 paint() 这个 CSS <image> 函数创建自定义值。然后,你可以将这些值应用于像 background-image 这样的属性,在一个元素上设置复杂的自定义背景。

例如:

aside {
  background-image: paint(myPaintedImage);
}

该 API 定义了 PaintWorklet,一个可以用来以编程方式生成响应计算样式变化的图像的 worklet。要了解更多关于如何使用它的信息,请查阅使用 CSS Painting API

接口

PaintWorklet

以编程方式生成图像,其中 CSS 属性需要一个文件。通过 CSS.paintWorklet 访问此接口。

PaintWorkletGlobalScope

paintWorklet 的全局执行上下文。

PaintRenderingContext2D

实现 CanvasRenderingContext2D API 的子集。它有一个输出位图,是它所渲染的对象的大小。

PaintSize

返回输出位图的宽度和高度的只读值。

字典

PaintRenderingContext2DSettings

提供 CanvasRenderingContext2D 设置的子集的字典。

实例

为了 在 CSS 中使用 JavaScript 直接绘制元素的背景,我们使用 registerPaint() 函数定义了一个 paint worklet,使用 paintWorkletaddModule() 方法告诉文档包含这个 worklet,然后使用 CSS paint() 函数包含我们创建的图像。

我们使用 registerPaint() 函数创建名为 “hollowHighlights” 的 PaintWorklet

registerPaint('hollowHighlights', class {

  static get inputProperties() { return ['--boxColor']; }

  static get inputArguments() { return ['*','<length>']; }

  static get contextOptions() { return {alpha: true}; }

  paint(ctx, size, props, args) {
		const x = 0;
		const y = size.height * 0.3;
		const blockWidth = size.width * 0.33;
		const blockHeight = size.height * 0.85;

		const theColor = props.get( '--boxColor' );
		const strokeType = args[0].toString();
		const strokeWidth = parseInt(args[1]);

		console.log(theColor);

		if ( strokeWidth ) {
			ctx.lineWidth = strokeWidth;
		} else {
			ctx.lineWidth = 1.0;
		}

		if ( strokeType === 'stroke' ) {
			ctx.fillStyle = 'transparent';
			ctx.strokeStyle = theColor;
		} else if ( strokeType === 'filled' ) {
			ctx.fillStyle = theColor;
			ctx.strokeStyle = theColor;
		} else {
			ctx.fillStyle = 'none';
			ctx.strokeStyle = 'none';
		}

		ctx.beginPath();
		ctx.moveTo( x, y );
		ctx.lineTo( blockWidth, y );
		ctx.lineTo( blockWidth + blockHeight, blockHeight );
		ctx.lineTo( x, blockHeight );
		ctx.lineTo( x, y );
		ctx.closePath();
		ctx.fill();
		ctx.stroke();

		for (let i = 0; i < 4; i++) {
			let start = i * 2;
			ctx.beginPath();
			ctx.moveTo( blockWidth + (start * 10) + 10, y);
			ctx.lineTo( blockWidth + (start * 10) + 20, y);
			ctx.lineTo( blockWidth + (start * 10) + 20 + blockHeight, blockHeight);
			ctx.lineTo( blockWidth + (start * 10) + 10 + blockHeight, blockHeight);
			ctx.lineTo( blockWidth + (start * 10) + 10, y);
			ctx.closePath();
			ctx.fill();
			ctx.stroke();
		}
  }
});

然后,我们包含 paintWorklet

<ul>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
    <li>item 4</li>
    <li>item 5</li>
    <li>item 6</li>
    <li>item 7</li>
    <li>item 8</li>
    <li>item 9</li>
    <li>item 10</li>
    <li>item 11</li>
    <li>item 12</li>
    <li>item 13</li>
    <li>item 14</li>
    <li>item 15</li>
    <li>item 16</li>
    <li>item 17</li>
    <li>item 18</li>
    <li>item 19</li>
    <li>item 20</li>
</ul>
  CSS.paintWorklet.addModule('https://mdn.github.io/houdini-examples/cssPaint/intro/worklets/hilite.js');

然后,我们可以使用 和 CSS paint() 函数:

li {
   --boxColor: hsla(55, 90%, 60%, 1.0);
   background-image: paint(hollowHighlights, stroke, 2px);
}

li:nth-of-type(3n) {
   --boxColor: hsla(155, 90%, 60%, 1.0);
   background-image: paint(hollowHighlights, filled,  3px);
}

li:nth-of-type(3n+1) {
   --boxColor: hsla(255, 90%, 60%, 1.0);
   background-image: paint(hollowHighlights, stroke, 1px);
}

我们在选择器块中包含了一个自定义属性,用于定义 boxColorPaintWorklet 可以访问自定义属性。

规范

规范 状态 备注
CSS Painting API Level 1 工作草案 初始定义。

浏览器兼容性

请参阅每个 CSS Painting API 接口的浏览器兼容性数据。

相关链接