使用 CSS 剪切路径创建交互效果,第二部分

Avatar of Mikael Ainalem
Mikael Ainalem

DigitalOcean 提供适用于您旅程各个阶段的云产品。立即开始使用 200 美元的免费积分!

这是我之前文章 关于剪切路径 的后续文章。上次,我们深入研究了剪切的基本原理以及如何入门。我们看了一些例子来说明我们可以用剪切做什么。在本文中,我们将更进一步,看不同的例子,讨论替代技术,并考虑如何处理我们的工作以实现跨浏览器兼容性。

截至撰写本文时,CSS 剪切最大的缺点之一是浏览器支持。没有 100% 的浏览器覆盖范围意味着不同浏览器中的用户体验不同。我们作为开发者,无法控制哪些浏览器支持 — 浏览器供应商是实现规范的人,不同的供应商会有不同的议程。

我们可以做的一件事是使用替代技术来克服不一致性。CSS 和 SVG 的功能集有时会重叠。在一种技术中有效的,在另一种技术中也可能有效,反之亦然。碰巧的是,剪切的概念在 CSS 和 SVG 中都存在。SVG 剪切语法非常不同,但效果相同。与 CSS 相比,SVG 剪切的优点是其成熟度。从旧的 IE 浏览器开始,支持率就很高。到目前为止,大多数错误都已修复(或者至少希望如此)。

SVG 剪切支持如下所示

此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
4311123.2

移动设备/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
1271274.43.2

剪切作为过渡

剪切的一个巧妙用例是过渡效果。看看 CodePen 上的 The Silhouette Slideshow 演示

查看 Pen 剪影缩放幻灯片,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。

一个“普通”的幻灯片会循环播放图像。在这里,为了让它更有趣,在切换图像时有一个剪切效果。下一张图像通过前一张图像的剪影进入屏幕。这会产生一种错觉,即图像相互连接,即使它们实际上没有连接。

过渡遵循以下过程

  1. 识别图像的焦点(即主要主题)
  2. 为该对象创建剪切路径
  3. 用路径剪切下一张图像
  4. 剪切的图像(剪影)淡入
  5. 缩放剪切路径,直到它大于视窗
  6. 完成过渡以显示下一张图像
  7. 重复!

让我们分解一下这个序列,从第一张图像开始。我们将把它分成多个 Pen,以便我们可以隔离每个步骤。

剪影缩放幻灯片解释 I,作者 Mikael Ainalem (@ainalem) 在 CodePen 上。

这是 SVG 标记的基本结构

<svg>
  ...
  <image class="..." xlink:href="..." />
  ...
</svg>

对于这张图像,我们接下来想要创建一个焦点蒙版 — 在这种情况下,是人物的剪影。如果您不确定如何创建剪切,请查看我的 之前的文章 以了解更多详细信息,因为总的来说,在 CSS 和 SVG 中进行剪切在基本原理上是相同的

  1. 将图像导入 SVG 编辑器
  2. 围绕对象绘制路径
  3. 将路径转换为 SVG 剪切路径的语法。这就是放在 SVG 的 <defs> 块中的内容。
  4. 将 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 内容。只有你的想象力才是限制。

如果你碰巧使用我们在这里介绍的内容创建了一些很酷的东西,请在评论中与我分享!