CSS加载动画 - 马赛克涟漪效果(关键帧,弹性盒)
结果
今天我们来学习 CSS 动画、延迟和 flex 盒子,以便在彩色马赛克上创建一个漂亮的涟漪效果。
阅读全文或在 YouTube 上观看我的编程演示:
结果
标记
这个加载器的标记非常简单,它由一个包装div.mosaic-loader和 16div.cell个元素组成。像 Pug 这样的模板引擎在这里可以起到很大的帮助,因为它只需要我们编写几行代码,而不是复制粘贴大量的代码。
- const cells = 4;
.mosaic-loader
- for (let i = 0; i < cells; i++)
- for (let j = 0; j < cells; j++)
div(class='cell d-' + (i + j))
展开后的 HTML 代码如下所示。请注意,每隔 4 行,d-n类名的值都会递减。这是因为类名i+j会将行索引和列索引相加,从而形成对角线对称。这对于后续正确管理动画延迟至关重要。
<div class="mosaic-loader">
<div class="cell d-0"></div>
<div class="cell d-1"></div>
<div class="cell d-2"></div>
<div class="cell d-3"></div>
<div class="cell d-1"></div>
<div class="cell d-2"></div>
<div class="cell d-3"></div>
<div class="cell d-4"></div>
...8 more with d2-5 and d3-6
</div>
基础 CSS
基础 CSS 代码一方面包含容器的设置,另一方面包含每个单元格的设置。一开始--cell-size会定义一些自定义 CSS 属性,以便我们能够轻松地针对不同用例自定义加载器的外观。不妨亲自尝试一下,并在嵌入的代码示例中调整这些值。
包装器本身是一个flex容器,允许其子元素被包裹在其中。通过计算--total-size一行中每个元素所需的宽度,并将其设置为包装器的宽度,可以确保整个加载器呈正方形。
.mosaic-loader {
--cell-size: 64px;
--cell-spacing: 0px;
--border-width: 1px;
--cells: 4;
--total-size: calc(var(--cells) * (var(--cell-size) + 2 * var(--cell-spacing)));
--cell-color: white;
display: flex;
width: var(--total-size);
height: var(--total-size);
flex-wrap: wrap;
对于每个单元格,flex配置方式使其既不能缩小也不能增大(0 0),并且始终保持在弹性基准(在本例中为宽度)处--cell-size。
.mosaic-loader {
...
> .cell {
flex: 0 0 var(--cell-size);
height: var(--cell-size);
margin: var(--cell-spacing);
box-sizing: border-box;
background-color: transparent;
border: var(--border-width) solid var(--cell-color);
}
}
动画本身
现在,动画本身设置为持续播放 1.5 秒,并无限循环。关键帧的配置使得动画在 0% 到 30% 的时间内,画面会background-color从透明逐渐过渡到透明,--cell-color直到 60% 时再次过渡回透明。因此,在动画剩余的 40% 时间内,画面保持透明,以便与其他画面进行一些重叠。
.mosaic-loader {
> .cell {
animation: 1.5s ease ripple infinite;
animation-delay: 0s;
}
}
@keyframes ripple {
0% {
background-color: transparent;
}
30% {
background-color: var(--cell-color);
}
60% {
background-color: transparent;
}
100% {
background-color: transparent;
}
}
应对延误
如前所述,要产生实际的涟漪效应,需要正确控制对角线之间的延迟。不同延迟的数量通过每行单元格的数量乘以 2 再减去 2 来计算。每一步之间,延迟增加 100 毫秒,从而使相邻对角线之间产生一些时间上的重叠。
.mosaic-loader {
> .cell {
$delays: (2 * 4) - 2;
@for $i from 1 through $delays {
&.d-#{$i} {
animation-delay: $i * 100ms;
}
}
}
}
让它色彩缤纷
最后,为了让界面更加色彩缤纷,只需创建一个包含 16 种颜色的数组,然后通过:nth-child选择器应用它们即可。更棒的是,通过使用--cell-colorCSS 自定义属性,可以单独覆盖每个单元格的颜色。
.mosaic-loader {
> .cell {
$colors: (
...16 colors of your choice
);
@for $i from 1 through length($colors) {
&:nth-child(#{$i}) {
--cell-color: #{nth($colors, $i)};
border-color: var(--cell-color);
}
}
}
}