Chrome 65 的新机遇
CSS Paint API(也称为“CSS Custom Paint”或“Houdini’s Paint worklet”) 从 Chrome 65 开始默认处于启用状态。Google 优惠是什么?可以采取的措施 该怎么办?它的工作原理是什么?请继续阅读,你会不会...
借助 CSS Paint API,您可以通过编程方式,
属性需要图片。媒体资源(例如 background-image
或 border-image
)
通常与 url()
结合使用,用于加载图片文件或与内置的 CSS 结合使用
函数,如 linear-gradient()
。您不用再使用这些变量
paint(myPainter)
,用于引用绘制 Worklet。
编写 Paint Worklet
如需定义名为 myPainter
的绘制 Worklet,我们需要加载 CSS 绘制
使用 CSS.paintWorklet.addModule('my-paint-worklet.js')
创建 Worklet 文件。在该部分中,
因此可以使用 registerPaint
函数注册绘制 worklet 类:
class MyPainter {
paint(ctx, geometry, properties) {
// ...
}
}
registerPaint('myPainter', MyPainter);
在 paint()
回调内,我们可以使用 ctx
,就像使用
与 <canvas>
中的 CanvasRenderingContext2D
相同。如果您知道如何
在 <canvas>
中绘制后,您可以在 Paint Worklet 中绘制!geometry
告诉我们
画布的宽度和高度。properties
我会
我们将进一步讨论此问题
作为一个入门示例,我们编写一个棋盘格颜料 Worklet 并使用它
用作 <textarea>
的背景图片。(我使用文本区域是
可默认调整大小):
<!-- index.html -->
<!doctype html>
<style>
textarea {
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
paint(ctx, geom, properties) {
// Use `ctx` as if it was a normal canvas
const colors = ['red', 'green', 'blue'];
const size = 32;
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
const color = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x * size, y * size, size, size);
ctx.fill();
}
}
}
}
// Register our class under a specific name
registerPaint('checkerboard', CheckerboardPainter);
如果您以前使用过 <canvas>
,应该不会对此代码感到熟悉。请参阅
直播
演示
此处。
![以棋盘图案作为背景图片的文本区域](https://developer.chrome.google.cn/static/blog/paintapi/image/textarea-a-checkerboard-bd94c5b6c6b65.png?authuser=0000&hl=nb)
与此处使用普通背景图片的不同之处在于: 每当用户调整文本区域的大小时,都会按需重新绘制。这意味着 背景图片的大小始终完全符合要求,包括 为高密度显示屏提供补偿。
这很酷,但同时也是静止的。我们要不能编写新的 每次我们想要相同的图案,但大小不同 正方形?答案是否定的!
将 Worklet 参数化
幸运的是,Paint Worklet 可以访问其他 CSS 属性,
这个额外的参数 properties
就派上用场了。为该类指定 static
inputProperties
属性,您可以订阅任何 CSS 属性的变化,
包括自定义属性这些值将通过
properties
参数。
<!-- index.html -->
<!doctype html>
<style>
textarea {
/* The paint worklet subscribes to changes of these custom properties. */
--checkerboard-spacing: 10;
--checkerboard-size: 32;
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
// inputProperties returns a list of CSS properties that this paint function gets access to
static get inputProperties() { return ['--checkerboard-spacing', '--checkerboard-size']; }
paint(ctx, geom, properties) {
// Paint worklet uses CSS Typed OM to model the input values.
// As of now, they are mostly wrappers around strings,
// but will be augmented to hold more accessible data over time.
const size = parseInt(properties.get('--checkerboard-size').toString());
const spacing = parseInt(properties.get('--checkerboard-spacing').toString());
const colors = ['red', 'green', 'blue'];
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
ctx.fillStyle = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.rect(x*(size + spacing), y*(size + spacing), size, size);
ctx.fill();
}
}
}
}
registerPaint('checkerboard', CheckerboardPainter);
现在,我们可以使用相同的代码绘制所有不同类型的棋盘。但 现在,我们可以进入开发者工具,摆弄这些值 直到找到合适的外观。
不支持绘制 Worklet 的浏览器
在撰写本文时,只有 Chrome 实现了绘制 Worklet。时间 是来自所有其他浏览器供应商的积极信号,因此进展不大。 如需随时掌握最新动态,请参阅 Is Houdini Ready Yet? 。在此期间,请务必使用渐进式 一些增强功能,即使在不支持绘制时也能确保代码正常运行 Worklet。为了确保一切按预期运行,您必须 CSS 和 JS。
您可以通过检查 CSS
对象来检测 JS 中对绘制 worklet 的支持:
js
if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('mystuff.js');
}
在 CSS 方面,您有两种选择。您可以使用 @supports
:
@supports (background: paint(id)) {
/* ... */
}
一个比较巧妙的技巧是,CSS 会让内容失效,随后 如果其中包含未知函数,则忽略整个属性声明。如果 您需要指定两次属性,第一次不使用 Paint Worklet,然后使用 绘制 Worklet - 您将获得渐进式增强:
textarea {
background-image: linear-gradient(0, red, blue);
background-image: paint(myGradient, red, blue);
}
在支持绘制 Worklet 的浏览器中,第二个声明是
background-image
将覆盖第一个。在不支持的浏览器中
对于 Paint Worklet,第二个声明无效,将被舍弃,
第一个声明才开始生效。
CSS 绘制 Polyfill
有多种用途,也可以使用 CSS 绘制 Polyfill、 它为现代浏览器添加了 CSS Custom Paint 和 Paint Worklets 支持。
使用场景
Paint Worklet 有很多用途,其中一些比
其他。其中比较显而易见的方法之一是使用 Paint Worklet 来缩减大小
DOM 的一部分。通常,添加元素纯粹是为了打造装饰
使用 CSS 文件例如,在 Material Design Lite 中,按钮
包含 2 个额外的 <span>
元素,用于实现
涟漪本身。如果您有很多按钮,那么这些按钮加起来可能会比较多
并可能导致移动性能下降。如果您
使用绘制 Worklet 实现涟漪效果
最终将得到 0 个其他元素,而只有一个 Paint Worklet。
此外,您还可以更轻松地自定义
参数化。
使用 Paint Worklet 的另一个优点是,在大多数情况下 就字节而言,使用绘制 worklet 很小。当然,还有 权衡:当画布尺寸或任意尺寸发生变化时,绘制代码就会运行 更改。因此,如果您的代码复杂且耗时较长, 卡顿。Chrome 正在努力将绘制 Worklet 移出主线程, 就算是长时间运行的 Paint Worklet,也不会影响主要 Paint Worklet 线程。
对我来说,最激动人心的前景是 Paint Worklet 能够实现高效的 对 CSS 功能进行 polyfill 操作。例如, 对圆锥梯度执行 polyfill 操作, 就会以原生方式登录 Chrome再比如,在一次 CSS 会议中, 决定现在可以有多种边框颜色这场会议的进行期间 工作之余,我的同事 Ian Kilpatrick 为这个新的 CSS 编写了一个 polyfill 绘制 Worklet 的行为。
跳出思维定式
大多数人在看到背景图片或边框图片时
Paint Worklet。Paint Worklet 有一个不太直观的用例,
mask-image
,可使 DOM 元素具有任意形状。例如,
diamond:
![一个菱形的 DOM 元素。](https://developer.chrome.google.cn/static/blog/paintapi/image/a-dom-element-the-shape-5de28c7a5eff9.png?authuser=0000&hl=nb)
mask-image
接受与元素大小相同的图片。哪些区域
表示图片是透明的,则该元素是透明的。戴口罩的区域
image 为 opaque,则元素不透明。
现已在 Chrome 中推出
Paint worklet 已在 Chrome Canary 版中推出一段时间。对于 Chrome 65, 默认处于启用状态开始尝试新的可能性 这个绘制 worklet 就会打开,让我们看看你构建了什么!如需更多灵感 查看 Vincent De Oliveira 的作品。
。