你是否还记得小时候剪过杂志上的照片,把它们粘在纸上,用来制作自己的拼贴画?这篇文章是关于使用CSS的clip-path
属性,用来实现Web上裁剪图片的效果。将讨论如何进行切割,以及如何使用这些镂空部件来制作一些有趣的效果。
我将以下面的照片为例。照片中的这朵花从照片中的其他部分脱颖而出。也变成一个自然的焦点。
创建SVG
首先,将示例图片导入其中创建一个新的SVG文件。你需要有处理矢量图的编辑软件,对图像进行切割。我使用的是一个免费的软件Inkscape,你也可以使用其他的应用程序,比如Adobe Illustrator((译:译者用的是Sketch)),甚至还可以使用在线编辑器,比如Vectr。
先在图像编辑器中创建一个新的SVG文档,其大小是100px
。使用100px
的正方形很重要,因为剪切路径的长度是百分比长度(length-percent)。选择0 ~ 100
的比例将允许从像素到百分比的无缝转换。
在继续下去之前,我发现一个非常有价值的事情是编辑器可以把SVG代码导出来。怎么导出SVG代码取决于应用程序。例如,在Illustrator中有两种方法。查看标记可以让我们了解编辑器在幕后做什么,因为并非所有应用程序都以相同的方式导出SVG。看到代码会增加你对标记的理解。这是一个双赢的选择。
导出的SVG代码类似下面这样:
<svg … width="100px" height="100px" viewBox="0 0 100 100"…>
...
</svg>
其中一个更重要的部分是SVG中的viewBox
属性,因为它代表了SVG的内部坐标系统。下面是对它如何工作的详细解释。上面的代码中可以看到,SVG的width
、height
和viewBox
的比例都是在0
到100
之间。
接下来是导入图像。在这里,我们要将图像大小调整为100px
,并将其置于原点(0,0)
。这样做可能会破坏图像的长宽比,除非你的图像是正方形。可我们的示例图并不是正方形,在后面运用clip-path
,这将不再会是问题。
再次查看导出来的代码,在SVG文件中可以看到<image>
元素。注意,preserveAspectRatio
设置为none
。这告诉我们图像的原始尺寸被忽略了。
<svg width="100px" height="100px" viewBox="0 0 100 100">
<image id="clip-path" x="0" y="0" width="100" height="100" xlink:href="data:image/png;base64,..."></image>
</svg>
特别声明:译者使用的是Sketch制图软件,导出来的SVG代码会有一大坨,像屎一样的难看,并且
<image>
的xlink:href
引入的是Base64图片。你也可以直接将图片的链接地址替换Base64代码。
屏蔽图像文件
现在来看看实际的图像切割。
切割图像的概念叫做掩蔽(masking)。如果你不熟悉masking,并不要紧,它本质上是用钢笔工具在图像勾画一个封闭的区域。就像是你不懂矢量编辑也可以做到这一点。不需要任何特殊的技术,你只需要几个基本步骤就可以搞定。
屏蔽位图就像从真正的杂志上剪下图像一样。这和在矢量编辑器中创建路径是类似的。选择钢笔工具,勾画出你想剪掉的部分轮廓。在这个示例中,就是图像中的花朵部分。在构造蒙层图像的过程中,你可以创造出许多你喜欢的东西。不过需要特别注意,一定要关闭路径。
在进行切割时,只使用cusp节点是很重要的,因为clip-path
不支持复杂的形状,比如贝塞尔曲线。它只支持简单的形状,比如polygon
、circle
和ellipse
。
如果我们现在查看导出来的SVG代码,那么输出的代码中会包含一个path
元素,其中包含你绘制的形状的坐标。下面的代码是我输出的路径的示例:
...
<path
d="m 52.843605,79.860084 -0.69448,1.767767 -0.883884,0 -1.26269,-1.578364 -0.757615,0.06314 -1.388959,-2.714785 -0.12627,-2.967323 -1.704632,2.525381 -1.136422,-0.126269 -0.505076,-2.841054 -1.515229,1.325825 -1.325825,-0.126269 -0.252538,-1.578363 -0.947018,-0.126269 -0.252538,-0.315673 -0.947018,0.126269 -0.69448,-0.757614 0.126269,-1.641498 -0.441942,-0.252538 -0.189403,-2.588516 -0.505077,-0.06314 -1.010152,0.568211 -0.568211,-1.452094 0.441942,-2.399112 -1.325825,-0.126269 -0.378808,-1.262691 0.378808,-2.08344 0.883883,-1.641498 -1.010152,-1.26269 0.505076,-1.957171 -1.452094,-1.010152 -0.378808,-1.010153 1.136422,-2.209709 -2.209709,-0.378807 -0.441941,-1.704632 0.631345,-2.020305 1.704632,-1.38896 -1.578363,-1.452094 0.568211,-2.462247 0.820749,-0.441942 0.126269,-1.515229 0.757614,-1.073287 0.441942,-1.515228 -0.505076,-1.38896 0,-2.272843 0.505076,-1.010153 1.136422,-0.505076 1.325825,0 0.06313,-0.568211 -0.947018,-2.08344 0.378807,-0.631345 0,-0.441942 1.073288,-0.69448 1.073287,0 0.56821,0.315673 -0.189403,-2.525381 0.189403,-0.883884 0.378808,0.757615 0.06313,-0.883884 0.378807,-0.378807 0.189404,-0.378807 0.126269,-2.08344 0.315673,0.06314 0,-0.568211 0.378807,-0.06313 1.199556,0.568211 0.505076,0.69448 0.252538,-2.08344 0.631346,-0.505076 0.631345,-0.568211 0.441942,-0.505076 0.252538,0.505076 0,-0.883883 1.262691,0.315673 0.820749,-1.894036 1.325825,1.136421 1.073287,-1.452094 0.820749,0.189403 1.010152,1.515229 0.505077,0.757615 0.631345,-1.452095 0.820749,-0.56821 0.820749,0.505076 0.378807,0.631345 0.820749,-0.189403 0.820749,0.947018 0,0.252538 0.69448,-0.126269 0.378807,0.631345 0.820749,0 0.568211,1.515229 0.378807,1.325825 0.505076,-0.189404 0.252538,0.441942 0.378808,0.126269 0.441941,2.08344 0,0.568211 0.505077,-0.126269 0,0.883883 0.694479,-0.252538 0.505077,0.505076 0.252538,0.947018 0,0.883884 0.315673,0 0.378807,0.631345 0.441941,0.631345 0.06314,1.515229 -0.378807,1.957171 -0.441942,1.767767 2.904189,-1.136422 0.252538,0.631345 0.126269,2.209709 -0.883884,1.830902 1.38896,0.378807 1.010153,1.199556 -0.378808,1.641498 -0.947018,1.767767 -0.505076,0.378807 0.69448,1.767767 1.010153,1.26269 0.378807,1.38896 -0.378807,1.515229 -0.568211,0.315673 -0.505077,1.010152 -1.452094,0.883884 0.189404,1.325825 0.315672,0.883883 -0.378807,1.38896 -1.388959,1.073287 -0.505077,0.126269 0,0.505077 -0.189403,1.830901 -1.010153,0.631345 0.820749,2.209709 -0.631345,1.452094 -1.641498,-0.189403 0.126269,1.578363 -0.315673,1.641498 -1.073287,0.505076 -0.378807,0.315673 -0.378807,0.883883 -0.252538,1.010153 0.06313,2.714785 -0.631345,0.631345 -1.578364,-0.883883 -0.757614,-1.262691 -0.189404,2.462247 0.189404,2.083439 -0.252538,2.588516 -0.441942,1.894036 -0.631345,0.631346 -0.631345,-0.189404 -0.820749,-0.883883 z"
/>
...
下面是我勾画花朵的录屏。
这是我的图像,在蒙层(mask)上有一点点不透明,以显示最后的形状被剪掉:
将SVG转换为CSS Clip Path
现在我们有了这个蒙版,接下来让我们看看如何从SVG变成clip-path
。这意味着在SVG代码中转换路径描述符或d
属性。
在我们研究如何进行转换之前,让我们讨论一下使用剪切路径的原因。你可能会问我们为什么要创建一个剪切路径?为会不在矢量图编辑器中屏蔽图像并导出预切图像呢?使用图像比使用大量的CSS代码要方便得多。但在我看来,使用剪切路径有两个主要好处:交互性和压缩。SVG本质上是DOM中的代码,它可以被操作,而且它的文件大小要比相同形状的位图图像小得多。
CSS剪切路径的语法与SVG中的语法有些相反。成对用逗号分隔,空格是单独的坐标。这与SVG描述符语法完全相反。为了使转换更加复杂,有些形状只使用绝对坐标。SVG路径更为灵活,因为它们可以同时使用两个坐标系统。
我创建了一个基本的节点脚本,它可以转换SVG路径。它在相对坐标中使用路径,并使用CSS的clip-path
输出相应的多边形。它使用正则解析SVG文件。可以明显的补充增加比例正常化。添加规范化将消除在创建掩码时只使用需要的正方形图形。
这是应用剪切路径到花朵上的照片效果:
使用CSS Clip Path的技巧
现在我们有裁剪的部分,接下来看看我们能做些什么。
叠加效果
一个有意思的效果就是将裁剪下出来的部分叠加在原图上。下面的示例,说明了在原始图像上叠加裁剪部分的思路。它会给你一个定位和两个不同部分的概念。有了这两个不同的元素,我们就有可能分别对前景和背景应用不同的效果。
高亮效果
图像上的某部分高亮不仅仅是视觉上的吸引,它还可以对你的网站的用户体验产生真正的影响。在Web页面中,你可能想要突出显示图像的某些部分,这并不难。在图像中某些部分高亮是一个用例。另一种方法是在产品展示中突出产品的某些特性。第三个案例可以是一张地图,你可以在其中高亮的地方讲一些有趣的事情。在适当地应用此功能增加用户的体验。使用剪切路径是在UI中实现高亮显示的一种方法。
回到刚才的图像中,现在可以很容易地使用花朵高亮。高亮实现的方法是通过降低其不透明度来降低花的背景:
我们可以在用户悬浮到花朵上时,花朵高亮显示。方法其一是添加JavaScript事件(addEventListener
)并将它们附加到蒙版元素上。通过像mouseenter
和mouseout
事件来捕获用户悬浮在花朵上。我们甚至可以切换背景的类名来触发效果。其中需要对CSS的opaticy
添加一个过渡效果。
我们甚至可以在同一张图像中多次重复上述这样的技术,让一个图像在多个地方高亮。
褪色和模糊效果
去年我看到背景图像模糊的效果,这是一种增强前景元素的反向方法。而不是增强前景元素本身,实现这样的效果可以将背景图像模糊,来达到同等的效果。这种增强前景元素的方法有另一个效果:当前焦点的元素保持不变,但同时,它也变得更加突出。
实现模糊效果的最简单的方法就是使用CSS中filter
的blur
。下面的示例与前面的示例类似,使用JavaScript的回调方法来触发鼠标悬浮的效果。它不是调整背景颜色,而是用CSS的filter
的blur
,并对其添加一定的过渡效果。
然而,使用CSS的filter
来实现模糊效果,对于性能而言是非常昂贵的。这与用于创建模糊效果的GPU上的着色器有关。使用CSS来实现模糊的动效不是一个很好的主意。一个更有效的选择是重用图像的预过滤版本,并使用交叉渐变(cross-fade)。换句话说,我们将复制的背景图像的不透明度变为动画,而不是对模糊做动效。其效果如下:
描边效果
另一种增强裁剪元素的效果是采用描边(outline)效果。重新使用蒙版是一个简单的方法。如果将SVG插入到两个主要元素之间,并添加一个scale
(本例使用的是1.04
),将其显示为一个较粗的描边效果。
当然,我们也可以在鼠标悬浮的时候触发元素描边效果,并为其添加一些动效:
蒙版的边缘有点粗。可以使用SVG过滤器给蒙版边缘进行一些软化效果的处理。如下所示:
镂空效果
如果想对剪掉的那么具有镂空效果呢?如果它显示了你想要扣掉部分背景呢?
例如,你想剪掉一个油炸的圈饼。然后你想通过蒙版把中间的洞排除在外。那你怎么去掉蒙版呢?除非我们使用SVG,否则clip-path
不允许我们这么做。这意味着一次创建多个形状是不可能的。
创建这些孔的一种方法是使用非常薄的连接器,把它画成一个形状。换句话说,可以从边缘切开一个很薄的切口,然后把洞挖出来。下面示例演示整个效果的过程:
形变效果
为了使高亮的效果更有效,我们实际可以修改clip-path
本身来实现。下面是一个示例,在示例中创建了一个蝴蝶动态高亮效果。在鼠标悬浮时,三种不同的切割部分之间高亮显示。
双重曝光效果
另外我们可以使用clip-path
创建双重曝光效果。在同一个蒙版中对两个图像做混合处理。
浏览器兼容性
那么现在可以在所有浏览器中使用clip-path
吗?不幸的是,目前还不能。在Caniuse上查看的话,你可以看到,他一片通红。
总结
我希望你能从这篇文章中掌握一些关键:
- 使用剪切路径是使图像高亮的一种方法
- 在原始图像上叠加裁剪部分,可以在图像中创建不同类型的高亮效果
- 可以通过蒙版对剪切部分创建交一些交互效果
clip-path
属性为用户体验提供了一种新的方式,可以对图像的各个部分进行高亮显示
本文根据@MIKAEL AINALEM的《Using CSS Clip Path to Create Interactive Effects》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://css-tricks.com/using-css-clip-path-create-interactive-effects/。
如需转载,烦请注明出处:https://www.w3cplus.com/css/using-css-clip-path-create-interactive-effects.html