魔法般的网页图片修剪!使用Houdini建立CSS剪切蒙版
作为设计开发人员,我们经常将CSS作为理所当然的生产工具。只需要调整一系列参数,我们就可以控制整个网页的样式,而浏览器将会替我们完成一系列复杂的渲染工作。
但当CSS有新功能出现的时候,我们却往往无法第一时间将它应用于生产。这不仅是开发者是否愿意学习的问题,而主要是用户的人均浏览器版本无法很快地跟上时代前沿,导致新的CSS效果无法很好地呈现给用户,甚至会出现恶性Bug。
而Houdini就是为了解决这个问题存在的,它整合了一系列开发规范,让开发者可以最大限度地利用CSS提供的功能。Houdini可以让用户设定的CSS用JavaScript进行算法和排版的规范化呈现。
Houdini可以做什么?
实际上,Houdini是一系列API,用以实现CSS和JavaScript功能的相互代替。在特定的浏览情境下,Houdini可以寻找到该浏览器版本最适合的渲染方式,并决定用CSS还是JavaScript交付给浏览器进行渲染。
Houdini服务于浏览器呈现内容的中间过程,它可以辅助特定内容比如动画的呈现,是一款轻量化专用型的工具。工作原理完全是网络API形式,即将特定内容从标准的浏览器信息流里分离出去单独进行处理,并以响应式方式返回到浏览器中。由于这种特性,Houdini有很好的可拓展性,未来支持的功能范围会更广。
目前这些API仍处于早期阶段,主要支持Chrome(v66版本)和Opera浏览器(v53版本)。CSS绘图API可以让开发者用JavaScript实现原本由CSS对图像做出的处理。如今开发者正致力于让Houdini适用于Safari浏览器,而更多API也即将登陆Chrome。目前Houdini的API已经符合W3C推荐标准,未来发展潜力很大。
使用Houdini来裁剪图片


我们这里展示的是Houdini的CSS绘图API(CSS Paint API),我们使用它来裁剪一张图片以展示它的功能和用法。
本次试用的示例文件可以在这里下载:https://www.filesilo.co.uk/tutorial-files/code-dynamic-backgrounds/
01 应用蒙版CSS
在开始工作之前,我们需要在本地创建一个服务器,然后在每个图片上加遮罩。我们在CSS需要加入mask-image属性,但仍需要为Chrome添加Webkit前缀。
打开style/mask.css,然后更新masked类。我们要实现的效果,是将鼠标悬停的时候显示完整的图片,否则显示剪切后的效果。
.masked {
[…]
-webkit-mask-image: paint(mask);
mask-image: paint(mask);
}
.masked:hover, .masked:focus {
--mask-reveal: true;
}
02 应用裁剪形状
自定义属性不需要写在根元素上,这样也可以被API拾取并应用在图形上面,并且会覆盖更低级别的选择器。
现在我们自定义裁剪三个形状,并将它定义在mask-shape上面,以告诉浏览器应该渲染为怎样的形状。
.masked.square {
--mask-shape: square;
}
.masked.circle {
--mask-shape: circle;
}
.masked.triangle {
--mask-shape: triangle;
}
03 定义使用的形状
打开scripts/mask.js,里面已经写好了创建形状的方式,我们需要将它和CSS关联在一起。
我们自定义的mask-shape属性应该可以决定裁剪使用的形状,因此我们需要定义circle、square和triangle三种选项。如果CSS里出现了非这三种选项的数值,那么我们默认用circle来代替。注意,CSS中的空格应该被删去。
let shape = ‘circle’;
if (properties.get(‘--mask-shape’) &&
[‘square’, ‘triangle’, ‘circle’]
.includes(properties.get(
‘--mask-shape’).toString().trim())){
shape = properties.get(
‘--mask-shape’).toString().trim(); }
04 定义展示方式
在我们想要的效果下,图像默认只展示边框,而在鼠标悬停的时候才展示内容。这样,我们就应该把默认的reveal设置为false,而悬停后则变为true。
let reveal = false;
if (properties.get(‘--mask-reveal’) &&
properties.get(‘--mask-reveal’)
.toString().trim() == ‘true’) {
reveal = true; }
05 定义尺寸
在最终效果中,我们希望每个图形的长边是相等的,这样看起来才比较和谐。因此,我们需要计算出每个图像边长的最大值以进行定义。
定义一个maxLength变量,然后用它来定义每个图像绘制时的边长即可。
const maxLength =
Math.min(geom.width, geom.height);
ctx.lineWidth = maxLength / 25;