最近《狂飙》大火,顺便蹭个热度,用CSS给狂飙做个转场动画。本文介绍了
4种
转场过渡效果,分别是
水平擦除转场
、
星型转场
、
时钟转场
,
自定义图形缩放转场
。
相信你肯定大有收获。
一个简单的渐变蒙版
CSS 蒙版允许您控制元素的显示情况。遮罩可以是
图像或渐变
。当蒙版应用于元素时,它充当一种映射。
遮罩可以使得元素部分被遮盖,从而产生半透明的样子。
下面的演示使用 CSS 遮罩将两图片交叉显示,呈现出淡入淡出。
第一个场景是
高启强
。第二个场景是
安欣
,他直接位于第一个场景之上。在第二个场景中使用渐变蒙版使其左侧透明,从而将第一个场景显示出。
CSS中主要是定位和调整大小,以及设置场景图像,但要
注意
.scene-2
上的
-webkit-mask-image
。
.wrapper {
width: min(1000px, 100%);
.scenes {
position: relative;
aspect-ratio: 2.4 / 1;
.scene-1, .scene-2 {
position: absolute;
inset: 0;
background-size: cover;
.scene-1 {
background-image: url(scene-1.jpg);
.scene-2 {
background-image: url(scene-2.jpg);
-webkit-mask-image: linear-gradient(to right, transparent 33%, #fff 67%);
在 -webkit-mask-image 上设置遮罩linear-gradient() ,表示从左到右的
前三分之一是完全透明的,所以这部分场景是不可见的。
中间的三分之一从透明变为不透明的白色,场景逐渐淡入。
最后三分之一是完全不透明的白色,导致这部分场景完全可见。
透明像素隐藏,不透明像素显示。颜色甚至都不重要。任何颜色都可以。
另外,我使用的前缀为 -webkit-mask-image (所有主流浏览器均支持),但不使用 mask-image (目前仅 Firefox 和 Safari 可识别)。
.scene-2 {
-webkit-mask-image: linear-gradient(to right, transparent 33%, #fff 67%);
mask-image: linear-gradient(to right, transparent 33%, #fff 67%);
水平擦除过渡转场
第一个场景过渡效果,即水平淡入淡出。
基本的 HTML 和 CSS 设置与上次相同。再一次,遮罩是一个 linear-gradient() ,从中间从 transparent 渐变到 #fff 。
那么淡入淡出是如何在场景中动画化的呢?
下方的可视化器。遮罩被拉伸到比实际场景更宽,然后动画水平滑动。
.scene-2 {
background-image: url(scene-2.jpg);
-webkit-mask-image: linear-gradient(
to right,
transparent 47.5%,
#fff 52.5%
-webkit-mask-size: 210%;
-webkit-mask-position: left;
.scenes:is(:hover, :focus) .scene-2 {
-webkit-mask-position: right;
transition: -webkit-mask-position 2s linear;
遮罩的大小为 -webkit-mask-size: 210% 为场景提供了 100% 的宽度,
最终形成:开始完全透明 + 10% 的淡入淡出 + 另一个完全不透明。
为了显示场景,我们将 -webkit-mask-position 的值设为 transition ,因此遮罩从 left 对齐变为 right 对齐。请注意, background-image 不会移动,只有遮罩会移动。
CSS 遮罩不仅遮罩了元素的背景,它还遮罩了整个元素及其中的所有内容。
接下来是星形转场,从中间淡出场景。注意,动画依赖于 CSS properties and values API。
这次我们使用 radial-gradient() 作为遮罩。我们还需要以下方式处理动画。
定义 radial-gradient() 。然后我们可以对该自定义属性进行动画处理以对渐变进行动画处理。
但在此之前,我们需要使用 @property 注册自定义属性。
@property --radius {
syntax: '<percentage>';
inherits: true;
initial-value: -5%;
--radius 的自定义属性,它保存 percentage 值并且默认值为 -5% 。并使用简单的关键帧动画为 --radius 设置动画。
@keyframes scene-transition {
to { --radius: 105%; }
将 .scene-2 的 CSS组合在一起。
.scene-2 {
background-image: url(scene-2.jpg);
z-index: -1;
-webkit-mask-image: radial-gradient(
circle,
#fff calc(var(--radius) - 5%),
transparent calc(var(--radius) + 5%)
.scenes:is(:hover, :focus) .scene-2 {
z-index: 1;
animation: scene-transition 2s linear forwards;
radial-gradient() 中的颜色停止位置也是如此。是 --radius 值的 -5% 和 +5% ,创建出渐变淡入淡出。
淡入淡出是 --radius 的值从 -5% 变为 105% 的原因。我们在开始时额外多出的 5% 确保所有像素都隐藏,然后在最后多出 5% 以确保所有像素都可见。
但是这个 API 在 Firefox 和 Safari 中不起作用。我们可以将 .scene-2 设置 z-index: -1 ,将其隐藏在第一个场景后面,然后改成 z-index: 1 以将其显示在第一个场景之上。
我们使用 conic-gradient() 为 angle 值设置动画。
@property --angle {
syntax: '<angle>';
inherits: true;
initial-value: -10deg;
@keyframes scene-transition {
to { --angle: 370deg; }
.scene-2 {
background-image: url(scene-2.jpg);
z-index: -1;
-webkit-mask-image:
conic-gradient(
#fff 0deg,
#fff calc(var(--angle) - 10deg),
transparent calc(var(--angle) + 10deg),
transparent 360deg
conic-gradient(
transparent 340deg,
#fff 360deg
.scenes:is(:hover, :focus) .scene-2 {
z-index: 1;
animation: scene-transition 2s linear forwards;
我们在 -webkit-mask-image 中使用了两个渐变。第一个 conic-gradient() 被动画化以创建时钟擦除效果,但它在其起点( 0deg 处)。渐变结合在一起为场景创建蒙版。
自定义图形缩放转场
.scene-2 的 CSS
@keyframes scene-transition {
25% {
filter: brightness(100%);
100% {
filter: brightness(100%);
-webkit-mask-size: 1800%;
.scene-2 {
background-image: url(scene-2.jpg);
filter: brightness(0%);
-webkit-mask-image: url(jedi-crest.svg);
-webkit-mask-size: 10%;
-webkit-mask-position: center;
-webkit-mask-repeat: no-repeat;
.scenes:is(:hover, :focus) .scene-2 {
animation: scene-transition 4s cubic-bezier(1, 0, 1, 1) forwards;
这次没有渐变。相反, -webkit-mask-image 是一个 SVG,将 .scene-2 遮罩。遮罩位于场景的 center 中,大小为 10% 。添加 filter: brightness(0%) 会消除所有亮度,导致 SVG 完全变黑。
动画使用 cubic-bezier() 曲线,开始时非常慢,然后变得非常快。
-webkit-mask-size 从 10% 到 1800% 动画化,使得绝地 SVG 中间的狭窄部分变得足够大以覆盖整个场景。
filter: brightness() 从 0% 到 100% 动画,场景从黑色淡化回正常。这部分动画设置为在 -webkit-mask-size 完成生长之前在 25% 时间标记处结束。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天
点击查看活动详情