这是我之前文章 关于剪切路径 的后续文章。上次,我们深入研究了剪切的基本原理以及如何入门。我们看了一些例子来说明我们可以用剪切做什么。在本文中,我们将更进一步,看不同的例子,讨论替代技术,并考虑如何处理我们的工作以实现跨浏览器兼容性。
截至撰写本文时,CSS 剪切最大的缺点之一是浏览器支持。没有 100% 的浏览器覆盖范围意味着不同浏览器中的用户体验不同。我们作为开发者,无法控制哪些浏览器支持 — 浏览器供应商是实现规范的人,不同的供应商会有不同的议程。
我们可以做的一件事是使用替代技术来克服不一致性。CSS 和 SVG 的功能集有时会重叠。在一种技术中有效的,在另一种技术中也可能有效,反之亦然。碰巧的是,剪切的概念在 CSS 和 SVG 中都存在。SVG 剪切语法非常不同,但效果相同。与 CSS 相比,SVG 剪切的优点是其成熟度。从旧的 IE 浏览器开始,支持率就很高。到目前为止,大多数错误都已修复(或者至少希望如此)。
SVG 剪切支持如下所示
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
4 | 3 | 11 | 12 | 3.2 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 4.4 | 3.2 |
剪切作为过渡
剪切的一个巧妙用例是过渡效果。看看 CodePen 上的 The Silhouette Slideshow 演示
查看 Pen 剪影缩放幻灯片,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
一个“普通”的幻灯片会循环播放图像。在这里,为了让它更有趣,在切换图像时有一个剪切效果。下一张图像通过前一张图像的剪影进入屏幕。这会产生一种错觉,即图像相互连接,即使它们实际上没有连接。
过渡遵循以下过程
- 识别图像的焦点(即主要主题)
- 为该对象创建剪切路径
- 用路径剪切下一张图像
- 剪切的图像(剪影)淡入
- 缩放剪切路径,直到它大于视窗
- 完成过渡以显示下一张图像
- 重复!
让我们分解一下这个序列,从第一张图像开始。我们将把它分成多个 Pen,以便我们可以隔离每个步骤。
剪影缩放幻灯片解释 I,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
这是 SVG 标记的基本结构
<svg>
...
<image class="..." xlink:href="..." />
...
</svg>
对于这张图像,我们接下来想要创建一个焦点蒙版 — 在这种情况下,是人物的剪影。如果您不确定如何创建剪切,请查看我的 之前的文章 以了解更多详细信息,因为总的来说,在 CSS 和 SVG 中进行剪切在基本原理上是相同的
- 将图像导入 SVG 编辑器
- 围绕对象绘制路径
- 将路径转换为 SVG 剪切路径的语法。这就是放在 SVG 的
<defs>
块中的内容。 - 将 SVG 标记粘贴到 HTML 中
如果您精通编辑器,您可以在编辑器中完成上述大部分操作。大多数编辑器都对蒙版和剪切路径有很好的支持。我喜欢对标记有更多控制,因此我通常至少会手动完成一些工作。我认为在使用 SVG 编辑器和使用标记之间存在平衡。例如,我喜欢组织代码、重命名类并清理编辑器可能在其中添加的任何杂乱无章的东西。
Mozilla 开发者网络很好地 记录了 SVG 剪切路径。以下是一个简化的原始演示中使用的标记版本,让您了解剪切路径如何融入
<svg>
<defs>
<clipPath id="clip"> <!-- Clipping defined -->
<path class="clipPath clipPath2" d="..." />
</clipPath>
</defs>
...
<path ... clip-path="url(#clip)"/> <!-- Clipping applied -->
</svg>
让我们使用一个彩色矩形作为幻灯片中下一张图像的占位符。这有助于清晰地可视化被剪切掉的部分的形状,并能更清晰地了解形状及其移动。
剪影缩放幻灯片解释 II,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
现在我们有了剪影,让我们看一下实际的过渡。从本质上讲,我们正在查看过渡的两个部分,它们共同创造了效果
- 首先,蒙版淡入视野。
- 短暂延迟(200 毫秒)后,剪切路径向上缩放。
请注意向上缩放规则中的 translate 值。它用于确保蒙版在事物向上缩放时保持在焦点位置。这是这些过渡的 CSS
.clipPath {
transition: transform 1200ms 500ms; /* Delayed transform transition */
transform-origin: 50%;
}
.clipPath.active {
transform: translateX(-30%) scale(15); /* Upscaling and centering mask */
}
.image {
transition: opacity 1000ms; /* Fade-in, starts immediately */
opacity: 0;
}
.image.active {
opacity: 1;
}
以下是我们的结果 — 一张过渡到矩形的图像!
剪影缩放幻灯片解释 III,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
现在让我们用下一张图像替换矩形以完成过渡
剪影缩放幻灯片解释 IV,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
对每张图像重复上述过程,就可以获得多个幻灯片。
我们需要的最后一件事是循环播放图像的逻辑。这是一个记账问题,确定当前图像和下一张图像,以此类推
remove = (remove + 1) % images.length;
current = (current + 1) % images.length
请注意,此示例在撰写本文时不受 Firefox 支持,因为它不支持缩放剪切路径。我希望这在不久的将来得到解决。
剪切以使前景对象从背景中出现
剪切的另一个有趣用途是用于显示和隐藏效果。我们可以创建视图的一部分,其中对象部分或完全隐藏,这是一种有趣的方式,可以使背景图像与前景内容交互。例如,我们可以让对象消失在背景图像中的元素后面,例如建筑物或山脉。当我们将这个想法与动画或滚动效果结合在一起时,它变得更加有趣。
查看 Pen 视差剪切,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
此示例使用剪切路径来创建一种效果,即文本淹没在照片中 — 特别是在用户向下滚动页面时,漂浮在山脉后面。为了让它更有趣,文本会随着视差效果移动。换句话说,不同的图层以不同的速度移动以增强透视感。
我们从一个简单的 div 开始,并在 CSS 中为它定义背景图像
视差剪切解释 I,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
照片中的关键部分是将前景层与照片背景层分隔开的线。基本上,我们想将照片分成两部分 — 这是剪切的完美用例!
让我们遵循之前介绍的相同过程,通过沿着一条线进行剪切来剪切元素。在您的照片编辑器中,在这两个图层之间创建剪切路径。我的做法是绘制一条沿着照片中的线进行的路径。为了封闭路径,我将这条线与顶角连接起来。
以下是使用蓝色突出显示背景层的视觉效果
视差剪切解释 II,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
任何绘制在蓝色区域下方的 SVG 内容都将被部分或完全隐藏。这会产生一种错觉,即内容消失在山丘后面。例如,以下是一个圆形,当它与前景层重叠的一部分时,它被绘制在蓝色背景之上
视差剪切解释 III,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
看起来有点像月亮从山顶探出来!
要重现我的原始演示,剩下的就是将圆形改为文本,并在用户滚动时移动它。一种方法是使用滚动事件监听器
window.addEventListener('scroll', function() {
logo.setAttribute('transform',`translate(0 ${html.scrollTop / 10 + 5})`);
clip.setAttribute('transform',`translate(0 -${html.scrollTop / 10 + 5})`);
});
不要过多地关注在计算距离时使用的 + 5。它只是作为一种粗略的方法来偏移元素。重要的是将事物除以 10 的地方,这会产生视差效果。滚动一定量会按比例移动元素和剪切路径。模板文字将计算出的值转换为字符串,该字符串用作变换属性值的偏移量,用于 SVG 节点。
组合剪切和遮罩
剪切和遮罩是两个有趣的概念。一种可以剪切内容的一部分,而另一种可以做相反的事情。这两种技术本身都有用,但我们没有理由不能将它们的力量结合起来!
组合剪切和遮罩时,您可以将对象分开,以对不同部分创建不同的视觉效果。例如
查看 Pen 视差徽标混合,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
我使用裁剪和遮罩在徽标上创建了这种效果。文本被分成两部分,与背景图像融合在一起,背景图像是一张纽约自由女神像的精美单色图像。我在文本的不同部分使用不同的颜色和不透明度,使其脱颖而出。这会产生一种有趣的视觉效果,当文本与雕像重叠时,它会与背景融合——在原本灰色的图像中增添一抹色彩。除了裁剪和遮罩,这里还存在视差效果。当用户将鼠标悬停在图像上或移动(触摸)图像时,文本相对于图像以不同的速度移动。
为了说明这种行为,以下是我们去除遮罩部分后得到的结果。
视差徽标混合解释 I by Mikael Ainalem (@ainalem) on CodePen.
这本身其实是一个很酷的功能,因为文本看起来像是在雕像后面流动。这很好地利用了裁剪。但是,我们要混合一些创意遮罩,让文本与雕像融合在一起。
这是相同的演示,但应用了遮罩并禁用了裁剪。
视差徽标混合解释 II by Mikael Ainalem (@ainalem) on CodePen.
注意遮罩如何将文本与雕像结合在一起,并使用雕像作为文本的视觉边界。裁剪允许我们显示完整的文本,同时保持这种融合。同样,最终的结果
查看 Pen 视差徽标混合,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。
总结
裁剪是一种创建交互和视觉效果的有趣方法。它可以增强幻灯片或使对象在图像中脱颖而出,等等。SVG 和 CSS 都提供了将剪切路径和遮罩应用于元素的能力,尽管语法不同。如今,我们可以剪切几乎所有 Web 内容。只有你的想象力才是限制。
如果你碰巧使用我们在这里介绍的内容创建了一些很酷的东西,请在评论中与我分享!
这简直太棒了,高达 101%。说真的,它已经达到了一个全新的酷炫程度。我一直关注你在 codepen 上关于 SVG 的作品,每次都让我大开眼界。
由于你之前的帖子评论已关闭……有人在那争论使用 CSS
:hover
而不是 javascriptmouseenter
,也许你可以使用parent:hover
,将pointer-events
设置为父元素的none
和子元素的auto
似乎 Firefox 无法动画化剪切路径。
Firefox **可以** 动画化剪切路径,它无法做的是缩放它。
很棒的文章。它激发了今晚我制作的一个小代码共享小部件的可视化效果。看一看!!https://codepen.io/quinlo/full/KxVGvL
太棒了!谢谢
顺便说一下,我发现了一个可以帮助生成剪切路径的不错工具 http://www.cssplant.com/clip-path-generator
很棒的演示,Mikael,感谢分享。特别是你的最后一个例子让我一直追寻一个困扰我的 SVG 未知问题,即:作为既是遮罩又是剪切路径使用的路径的最 DRY 的封装是什么?
看看我在 CodePen 上对你的视差徽标混合 SVG 的这个分支重排。我将所有讨厌的东西都转移到了一个单独的 SVG 中,并在任何无法展开的内容周围包装了标签——主要是为了提高可读性/可折叠性,但也为了减少数据重复:在字母路径的情况下成功了,但不知何故,在双重遮罩/剪切路径使用的情况下总是需要重复
Mikael 或任何对消除最后一段重复数据有任何想法的人,即目前拥挤着链接重构的遮罩和剪切组的 Liberty 路径数据?