首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

CSS Paint API

CSS Paint API是W3C规范中之一,目前的版本是Level1。它也被称为CSS Custom Paint或者Houdini's Paint Worklet。对于开发者而言,有一个值得高兴的是,Chrome65将会支持该API。也就是说,可以使用CSS Paint API提供的做一些事情。

那么CSS Paint API是什么?你能用它做什么?它又是如何工作的呢?带着一系列的为什么,我们开启对CSS Paint API的初探。

什么是CSS Paint

先来了解CSS Paint是什么?在理解这个概念之前,我们先来回忆一下,我们在平时写CSS时是如何给一个元素设置背景图片。了解CSS的同学,都应该知道,采用属性,比如:

background-image:url(xxx.jpg)

或者:

background-image:linear-gradient(to bottom, red, green)

除了给指定一个图片之外,还可以是渐变(CSS中的渐变相当于一张背景图片)。而我们要了解的CSS Paint则是通过JavaScript的方式,让你在CSS中能够引入用JavaScript编写的图形。感觉有点类似于HTML5中的,对吗?如果你继续往后看,你会越加有这样的感觉。

写一个Paint Worklet

先定义一个叫作的Paint Worklet,接下来使用来加载已定义好的CSS Paint Worklet。在文件中,使用函数来注册一个Paint Woklet的类:

classMyPainter{paint(ctx, geometry, properties) {// ...}}registerPaint('myPainter', MyPainter)

在回调中,我们可以使用中的方法。如果你熟悉,那么你就可以知道怎么绘制Paint Worklet。用来指定画布的和,可以获取自定义元素属性,这么说有点抽象,后面会介绍到该属性。

特别声明:CSS Paint中的Paint Worklet的和中的并不是百分之百的相同。到目前为止,文本渲染的方法是无法使用的,这主要是出于安全原因,你无法从画布上读取像素。

来看一个简单的示例。先创建一个文件:

body{

width:100vw;height:100vh;background-image:paint(checkerboard);}CSS.paintWorklet.addModule('checkerboard.js')

然后创建,并在这个文件中添加下面的代码:

classCheckerboardPainter { paint(ctx, geom, properties) {

constcolors = ['red','green','blue'];

constsize =32;

for(lety =; y

for(letx =; x

到时将会看到的效果如下所示:

上面的示例,先定义了一个叫的Paint Worklet,并且将之注册为,然后通过的方法加载这个Paint Worklet。最后在CSS中,使用给指定的元素添加背景图。其最终效果正如上图所示。

可能你会纳闷,这样的效果使用就能实现(不管是调用图片,还是使用都可以实现类似效果)。那他们两者之间有何区别吗?其实两者是有所区别的:

CSS Paint与的差别就是是根据代码计算出来的,不会随着元素的大小变化而伸缩。而CSS Paint绘制的图像总是会和元素容器所需保持一样的大。也就是说,让你修改元素大小可视区域时,CSS Paint绘制的图像会重新绘制。言外之意,背景图像总是和它所需要的一样大,包括对高密度(Hight-density)显示器的补偿。

是不是很酷。

个性化Paint Worklet

前面提到过,定义一个Paint Worklet时方法接受三个参数,其中第三个参数可以让Paint Worklet可以访问其他CSS属性,这就是参数的强大之处。通过一个静态的类,比如属性,你可以对任何CSS属性,包括自定义属性进行更改。这些值将通过参数提供给你。

比如下面这个例子。同样先创建一个文件,在文件中加入下面的代码:

body{

width:100vw;height:100vh;--checkerboard-spacing:10;--checkerboard-size:32;background-image:paint(checkerboard);}CSS.paintWorklet.addModule('checkerboard.js')

然后在创建的文件中加入下面的代码:

classCheckerboardPainter {

staticgetinputProperties() {

return[

'--checkerboard-spacing',

'--checkerboard-size'] } paint(ctx, geom, properties) {

constsize = parseInt(properties.get('--checkerboard-size').toString());

constspacing = parseInt(properties.get('--checkerboard-spacing').toString());

constcolors = ['red','green','blue'];

for(lety =; y

for(letx =; x

现在我们可以使用相同的代码来处理所有不同类型的格子效果。但更爽的是,现在可以通过开发者调试工具,在找到正确的外观之前,对这些值进行修改。

在 类中,给静态属性 定义了两个属性: 和 ,这两个属性可以像一般的 CSS 的属性一样使用于 HTML 元素,而这两个属性的值将被 的第三个参数 获得,被用于生产图像。所以,如果修改 的 或者 属性,背景图将会发生改变,正如上面的录屏展示的效果一样。

注意:如果把颜色也参数化是不是很有意?允许函数获取参数列表。这个特性还没有在Chrome中实现,因为它目前还严重依赖于Houdini的属性和值的API,让其能正常工作,还需要一些时间。

不支持Paint Worklet的浏览器

到目前为止,只有Chrome浏览器支持Paint Worklet(Chrome 65可以看到效果)。尽管其他浏览器都发出响应将会支持CSS Paint API的特性,但到目前依旧没有啥进展。为了跟上时代的发展,Houdini支持吗?与此同时,就算浏览器还不支持CSS Paint的Paint Worklet,我们也要确保使用渐进增加来保证你的代码能正常运行。为了确保这一点,你必须在CSS和JavaScript中调整你的代码。

如果你从未接触过Houdini,甚至说都不知道他是什么?建议你点击这里对Houdini进行一些简单的了解。另外这里有一个CSS Houdini的示例仓库,这些示例将向你展示Houdini的神奇之处。

回到正题上来吧,对于不支持的浏览器,可以通过检查CSS对象,实现对JavaScript中Paint Worklet支持情况做一个检测:

if('paintWorklet'inCSS) { CSS.paintWorklet.addModule('mystuff.js');}

而在CSS通过来做相应的检测:

@supports (background:paint(id)){

body{

background-image:paint(checkerboard);}

}

另外,众所周知,如果浏览器遇到一个未知的属性,则会忽略此属性声明的规则。如果你对同一个属性进行两次声明,前者是CSS的属性,其后紧跟Paint Worklet,你就可以对不支持CSS Paint的浏览器做降级处理。比如下面这样:

body{

background-image:linear-gradient(, red, blue);background-image:paint(myGradient, red, blue);

}

这样一来,支持CSS Paint的浏览器,第二个将会覆盖第一个。在不支持CSS Paint的浏览器,第二个属性规则将会示为无效,而第一个将会起作用。

示例

在众多CSS Paint的示例中,其中一些比其他的示列更易理解。其中一个比较易于理解的示例就是使用CSS Paint来减少对DOM元素。通常,元素的添加纯粹是为了使用CSS创建修饰。例如,在Material Design Lite中的的Ripple效果。为了实现这个效果,添加了两个额外的元素。如果你的Web页面有很多这样的按钮效果,那么你就要增加很多个DOM元素,因此可能影响你的页面性能。如果使用CSS Paint来实现Ripple效果,你不需要添加任何额外的DOM元素。此外,你还拥有更易于自定义的属性。

使用CSS Paint的另一个好处是,在大多数的情况下,能解决很多CSS无法解决的事情,而且代码量也少。当然,其中也有一个取舍问题。当画布的大小或任何参数发生变化时,绘图的代码将会运行。因此,如果你的代码很复杂,那需要很长的时间,它可能会引入jank。Chrome正在处理主要线程上的Paint Worklet,因此即使运行时间长,Paint Worklet也不会影响主线程的响应能力。

对于我来说,最令人兴奋的前景是,CSS Paint可以很快的为CSS新特性创建Polyfill。比如的Polyfill。另外的一个例子,在CSS会议中,它决定你现在可以有多个边框颜色。在这个会议还在进行之时,@Kilpatrick就通过CSS Paint为其写了一个对应的Polyfill。

不规则盒子的思考

大多数人在学习CSS Paint时都从和着手。其实另一个值得我们思考的是,如果使用 CSS Paint的可以让DOM元素具有任意形状。比如钻石形状:

写在最后

CSS Paint在Chrome Canary中已有一段时间。值得庆幸的是,在Chrome 65中将会默认启用CSS Paint。对于开发者而言,我们应该不断去尝试新的可能性,CSS Paint将会让我们打开更多的思路,为你的灵感提供更多于创作的空间。可以看看@Vincent De Oliveira收藏的一些案例。或许在这些案例中,你也能产生一些新的灵感。

特别声明:此篇文章内容来源于@Surma的《CSS Paint API》一文。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180131B01O4400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券