使用mask-image实现星球大战场景过渡效果

开发 前端
大家有看过星球大战这部电影吗,里面有许多场景间的过渡效果看起来非常的丝滑,那我们能不能使用CSS来模拟实现一下呢?

前言

大家有看过星球大战这部电影吗,里面有许多场景间的过渡效果看起来非常的丝滑,那我们能不能使用CSS来模拟实现一下呢?

渐变体验

如果mask-image以图像或渐变的形式出现,则我们可以控制与元素的哪些像素是可见的,哪些像素是不可见的(透明)。当mask-image应用于元素时,它充当一种映射,确定每个元素的可见性。

下面尝试将两张图片使用mask-image实现交叉淡入淡出效果

<template>
  <div :class="$style.xq_outer">
    <div :class="$style.xq_bg"></div>
    <div :class="$style.xq_women"></div>
  </div>
</template>

<style lang="scss" module>
.xq_outer {
  position: relative;
  width: 600px;
  height: 360px;
  margin: 20px auto;
  background: red;
}
.xq_bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_bg.jpeg");
  background-size: 100% 100%;
}
.xq_women {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_women.jpeg");
  background-size: 100% 100%;
  -webkit-mask-image: linear-gradient(to right, transparent 30%, #fff 44%);
}
</style>

效果是这样的:

图片

这里第一眼看上去你不会以为这就是一张图片吧,其实这是由星球背景 + 人物两张图片“合成”的。

是不是有点PS的感觉了。

「原理是:第一个场景是星球,第二个场景是人物,直接位于第一个场景之上。在第二个场景中使用渐变蒙版使其左侧透明,从而显示出第一个场景。」

-webkit-mask-image为linear-gradient()从左到右渐变。

  • 前三分之一是完全透明的,所以这部分人物图片是不可见的,底下的星球图片露出。
  • 中间的三分之一从透明变为不透明的白色,场景逐渐淡入。
  • 最后三分之一是完全不透明的白色,导致这部分人物图片完全可见,底下的星球完全被盖住。

水平擦除过渡

了解了上面这个效果的实现原理,我们就可以来着手实现第二个水平擦除效果了,从上面这个例子我们不难想象到只要蒙版拉伸到比实际场景更宽,然后动画水平滑动,就能够实现这个水平擦除效果了。

.xq_outer {
  position: relative;
  width: 600px;
  height: 360px;
  margin: 20px auto;
}
.xq_bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_bg.jpeg");
  background-size: 100% 100%;
}
.xq_women {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_women.jpeg");
  background-size: 100% 100%;
  // -webkit-mask-image: linear-gradient(to right, transparent 30%, #fff 44%);
  -webkit-mask-image: linear-gradient(to right, transparent 48%, #fff 52%);
  -webkit-mask-size: 210%;
  -webkit-mask-position: left;
}
.xq_outer:is(:hover) .xq_women {
  -webkit-mask-position: right;
  transition: -webkit-mask-position 2s linear;
}

效果如下:

图片

「原理:蒙版的大小为-webkit-mask-size: 210%- 这为场景提供了 100% 的宽度,最初是完全透明的 + 10% 的淡入淡出 + 另一个 100% 的场景最终完全不透明。」

光圈擦除过渡

下面再来看一种光圈擦除效果,这里将会使用到@property自定义属性,由于这个属性还处于实验阶段,所以在将其用于生产之前,请仔细检查浏览器兼容性表格。

大致的思路是:使用radial-gradient()在其中定义一个自定义属性。然后我们可以对该自定义属性进行动画处理以对渐变进行动画处理。但在此之前,我们需要将自定义属性注册到@property.

@property --r {
  syntax: "<percentage>";
  inherits: true;
  initial-value: -5%;
}

.xq_women {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_women.jpeg");
  background-size: 100% 100%;
  // -webkit-mask-image: linear-gradient(to right, transparent 30%, #fff 44%);
  // -webkit-mask-image: linear-gradient(to right, transparent 48%, #fff 52%);
  // -webkit-mask-size: 210%;
  // -webkit-mask-position: left;
  -webkit-mask-image: radial-gradient(
    circle,
    #fff calc(var(--r) - 5%),
    transparent calc(var(--r) + 5%)
  );
}

@keyframes circle {
  to {
    --r: 105%;
  }
}
.xq_outer:is(:hover) .xq_women {
  // -webkit-mask-position: right;
  // transition: -webkit-mask-position 2s linear;
  animation: circle 2s linear forwards;
}

再来看看此时的效果:

图片

「原理:随着 --radius 的动画化,radial-gradient() 中的色标位置也是如此。它们被计算为 --radius 值的 -5% 和 +5%,以创建渐变淡入淡出,为擦拭提供柔和的边缘。」

时钟擦除过渡

再来看一个星球大战中最具标志性的擦除过渡——时钟擦除过渡。这次我们使用conic-gradient()和动画化一个自定义属性angle值。

@property --angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: -10deg;
}

.xq_women {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("/public/xq_women.jpeg");
  background-size: 100% 100%;
  -webkit-mask-image: conic-gradient(
      #fff 0deg,
      #fff calc(var(--angle) - 10deg),
      transparent calc(var(--angle) + 10deg),
      transparent 360deg
    ),
    conic-gradient(transparent 350deg, #fff 360deg);
  z-index: -1;
}

@keyframes ang {
  to {
    --angle: 370deg;
  }
}
.xq_outer:is(:hover) .xq_women {
  animation: ang 2s linear forwards;
  z-index: 1;
}

效果如下:

图片

「原理:第一个conic-gradient()动画以创建时钟擦除效果,但它在其起点(在 处0deg)留下了硬边。这就是为什么要conic-gradient()在硬边缘之前创建一个小的淡入淡出并将其软化的原因。渐变结合在一起为场景创建蒙版。」

总结

现在的CSS功能越来越强大了,在本文中介绍了很多 CSS 成分,包括不同类型的渐变、注册自定义属性,当然还有遮罩和动画。这在以前,仅仅靠CSS是不可能实现的效果!

责任编辑:华轩 来源: 前端南玖
相关推荐

2016-09-28 00:32:46

2015-12-24 10:34:13

星球大战机器人

2012-10-19 09:31:21

GoogleFacebook数据中心

2012-11-12 16:47:56

2023-10-09 12:36:25

AI模型

2017-05-10 11:23:28

人工智能

2012-11-08 17:33:53

智慧云

2016-01-12 11:54:45

原力觉醒向日葵星球大战

2023-05-22 09:10:53

CSSloading 效

2010-06-13 14:56:48

WindowsLinux苹果

2023-10-09 13:11:31

2010-02-24 13:56:27

Python编程语言

2018-06-27 16:17:41

NIUDAY

2010-09-06 11:02:35

乔布斯

2022-02-24 11:16:38

量子计算机器学习黑洞

2009-09-09 09:37:38

谷歌苹果

2011-09-20 09:56:13

Google微软电子邮件

2022-09-16 14:26:56

恶意软件网络攻击

2021-02-23 11:27:06

mask CSS SVG

2020-05-15 10:26:36

终端macOSHomeBrew
点赞
收藏

51CTO技术栈公众号