CSS的mask-composite

CSS的mask(遮罩),有时也称CSS的蒙层,最早是苹果公司2008年提出的,并且添加到webkit引擎当中。遮罩提供一种基于像素级别的,可以控制元素透明度的能力,类型于png24位或png32位中的alpha透明通道的效果。2012年被纳入到W3C的草案中,但这个版本与苹果公司提出的版本是不同的。时至今日,该规范已经有多个版本,现在是CSS Masking Module Level1版本,属于TR阶段。据Caniuse.com统计来讲,该属性得到的支持度还是有一定的限制,仅部分属性被浏览器支持。虽然如此,但该属性还是非常的有意思,值得大家花点时间去探究,比如今天要聊的mask-composite属性就是非常有意思的一个属性。

mask原理和语法

文章开头也提到过,mask提供一种基于像素级别的,可以控制元素透明度的能力,类似于png24位或png32位中alpha透明通道的效果。

图像是由RGB三个通道以及在每个像素上定义的颜色组成的。但是在他们之上还有第四个通道,即alpha通道。通过高度定义每个像素上的透明度。白色意味着不透明,黑色意味着透明,介于黑白之间的灰色表示半透明。比如下图:

给一个HTML元素使用CSS的mask属性,就会这样处理。不用给图片应用一个alpha通道,只需要给一个图片运用一个mask-imagemask-border-source的样式:

mask-image: url(mouse.png)

他从图片遮罩里读出图片的透明信息,然后应用到HTML元素上,比如下图这个效果:

遮罩可以让头像按照特定形状显示。

CSS遮罩可以使得图片按照任意的形状显示。或者你可能有很长的文本需要滚动显示,那么可以使用遮罩让他从不透明到透明的渐变显示

在使用mask的时候,其中有一个不可或缺的部分就是遮罩(也被称为蒙板),该遮罩可以是半透明的PNG图片CSS的渐变SVG元素,遮罩元素的alpha值为0的时候会覆盖下面的元素,为1的时候会完全显示下面的内容。如下图所示:

而使用CSS的mask也并不太复杂,其语法规则和background非常的类似。在W3C官网上提供了两者相关属性的对照表:

mask属性 background属性
mask-clip background-clip
mask-image background-image
mask-origin background-origin
mask-position background-position
mask-repeat background-repeat
mask-size background-size
mask-mode  
mask-composite  
  background-attachment
  background-color

具体的语法规则:

mask: <mask-layer>

<mask-layer>对应的值:

<mask-layer> = <mask-reference> <masking-mode>? || <position> [ / <bg-size> ]? ||
<repeat-style> || <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator>

即:

mask: [mask-image] [mask-repeat] [mask-position] / [ mask-size]

background属性类似,建议mask-size单独写出来:

mask: [mask-image] [mask-repeat] [mask-position]
mask-size: [mask-size]

上面我们列出的的仅是mask部分属性,在规范中还提供了其他的属性,这几个属性有点类似于CSS中的border属性,比如mask-border-sourcemask-border-modemask-border-slicemask-border-widthmask-border-outsetmask-border-repeatmask-border等。另外还可以用于SVG,比如mask-type

上面简单的介绍了CSS中mask的基本原理和使用规则,但我们今天的重点并不是来了解所有的属性,而是针对性的学习其属性之一,即mask-composite属性。如果你想了解更多有关于mask相关的知识,建议你花点时间阅读下列文章:

mask-composite

mask-composite仅是CSS的mask的子属性之一。该属性的工作原理是什么?它有什么用?使用它的价值是什么?

如果将上述问题一一答出来之后,可以彻底让我们掌握mask-composite的原理和使用方式。@Ana Tudor新出的博文《Mask Compositing: The Crash Course》就详细介绍了这些,也称得上是mask-composite速成记。

特别声明,接下来的内容和图片资源来自于@Ana Tudor的《Mask Compositing: The Crash Course》一文!在此特别感谢@Ana Tudor为我们提供这么优秀的教程。

什么是遮罩合成

遮罩合成指的是我们可以使用不同的操作将多个不同的遮罩层合并成一个独立的遮罩层。那么问题来了?多个遮罩层是如何合并成一个呢?比如我们有两个遮罩层,在这两个遮罩层中取每对对应的像素,在它们的通道上应用特定的合成操作(具体合成的操作细节,后面会介绍),并为最终层获得第三个像素。如下图所示:

上图中左上图和左下图合层起来成了右侧的层。而左上图被称为源(Source),左下图被称为目标层(Destination),这对地我们来说没有多大的意义,因为给我的感觉一个是输入源,一个是输出结果(事实上,这两个都是输入),但是,就上图的结果而言,这两个层(源和目标层)却做了一个合层的操作(也被称为合层计算),从而得到最终的结果(上图右侧的合并层)。

上面演示的是仅有两个层合并,而事实上呢?我们可能会有两个以上的层合并,当有这种情形时,合层是分阶段完成的,从底部开始。

在第一阶段,从底部开始的第二层是源,从底部开始的第一层是目标,这两层被合层,结果成为第二阶段的目标,接着和从底部开始的第三层(源)合并。通过合成前两层的结果合成第三层,我们就得到了第三阶的目标,接着再从底部的第四层源合并。如下图这样的一个合并过程:

以此类推,直到我们达到最后一个阶段,在这里,最顶层由下面所有层的合成结果组成

遮罩合成有什么用?

CSS和SVG的遮罩都有各自的局限性和优缺点。我们可以通过使用CSS遮罩来绕过SVG遮罩的限制,但是,由于CSS的遮罩和SVG遮罩的工作方式不同,采用CSS遮罩我们无法在不进行合成的情况下实现某些结果。

为了更好地理解这一切,让我们来看看下面这张令人敬畏的西伯利亚小老虎的图片:

假设我们使用遮罩期望得到的效果如下图所示:

这个特殊的mask保持了菱形的可见性,而分隔它们的线被遮罩,我们可以通过图像看到后面的元素。

我们希望这种遮罩效果是灵活的。我们不希望与图像的尺寸或长宽比绑定,我们希望能够轻松地随图像缩放和不缩放的mask之间进行切换(只需要将%值更改为px)。

为了做到这一点,我们首先需要了解SVG和CSS的遮罩是如何工作,以及我们可以和不可以使用它们做什么。

SVG遮罩

SVG遮罩默认情况下是亮度(luminance)遮罩。这意味着遮罩元素上白色像素部分是完全不透明,而黑色像素部分是完全透明的,而遮罩元素白色和黑色像素之间的亮度(greypinklime)是半透明的。

给定RGB值对应亮度的计算公式为:.2126·R + .7152·G + .0722·B

对于我们这个示例,这意味着我们需要将菱形区域变成白色,分隔线是黑色,如下图所示:

为了得到上图的效果,使用SVG的rect绘制一个纯白色的矩形,然后使用path在这个矩形中添加两条黑色的对角线(确保stroke的值为black)。

先创建第一条对角线(从左上角到右下角),在左上角使用M命令,然后在右下角使用L命令;接着创建第二条对角线(从右上角到左下角),在右上角使用M命令,然后在左下角使用L

剩余70%内容付费后可查看
* 请输入阅读码(忘记阅读码?

如需转载,烦请注明出处:https://www.w3cplus.com/css/mask-compositing.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部