前情提要
最近比较忙一直没有发文,今天正好赶上1024程序节,蹭蹭热度发一篇。写这篇文章的思路,是最近我在外网看到的一篇文章启发的,那个外国博主写的很详细,几乎每步每个都有示例,由此我想着写一篇中文版的。
PS:那个国外博主的链接点击此处访问,大家如果想看原文记得开翻墙
基本原理
在查看代码之前,我们先来了解一下实现该效果的基本原理,首先旗帜是由多个宽高相当的长方形组成,并且沿着Y轴以从左到右的顺序进行上下移动,再以相反的顺序进行移动,以此循环实现效果。
了解了基本原理,接下来就可以根据我们自己的方法去实现,在这里可以看看博主的思路,首先宽高相当的长方形我们可以用多个 div 实现,并设立一个大 div 做为父级,通过设置 display:flex 属性实现子级div 同行,而上下移动效果我们可以用css3的 transform: translateY(0px) 属性实现,并且为了保持我们看到的效果更好,我们可以用 @keyframes 属性设置一个动画,并设置动画的时间及时间。代码如下。
javascript
<div class="flag">
<div style="background-color: lightcoral" />
<div style="background-color: lightsalmon" />
<div style="background-color: lightgoldenrodyellow" />
<div style="background-color: lightgreen" />
<div style="background-color: lightcyan" />
<div style="background-color: lightblue" />
<div style="background-color: purple" />
</div>
<style lang="less" scoped>
.flag {
display: flex;
padding: 15px;
}
@keyframes move {
from {
transform: translateY(-5px);
}
to {
transform: translateY(5px);
}
}
.flag div {
width: 30px;
height: 140px;
border-radius: 3px;
animation-name: move;
animation-duration: 500ms;
animation-iteration-count: infinite;
}
</style>
运行上述代码,我们可以看到效果是这样的,div 虽然上下移动了,但是每次运动的很突兀,并且没有从下到上的步骤,而且每个 div 运行轨迹一致,看不出旗帜效果,别急下面我们会具体解决。效果如下图。
飘动效果
小伙伴们看完了基本原理,可以知道我们最后实现的效果,是有很大瑕疵的,一是没有自右往左的循环显的很突兀,二是运动轨迹规律看不出旗帜效果。其实只要搞懂了上面的基础原理,这两个点都很好实现。
一自右往左循环,这点我们可以用到css3动画里的 animation-direction:alternate 属性来实现,通过设置改属性值,我们可以让动画的播放方式变为奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。如下图
二是运动轨迹规律看不出旗帜效果,这点我们可以用到css3动画里的 animation-delay:500ms 属性来实现,该属性值可以让动画延迟启动,我们可以借此功能从左到右为每个小div设置毫秒延迟数,越靠后的div延迟时间越长,以此时间旗帜飘动的效果。如下图
完整代码
通过上述尝试我们最终实现了旗帜效果,这个旗帜效果看起来花里胡哨,但是经过我们一步步拆解查看还是很简单的,其实不只是这个旗帜效果咱们见到的大多数撩人眼的特效,其底层原理都很简单,就看你会不会去拆解尝试。哈哈哈多的话不说,下面附上完整代码,小伙伴们可以自己尝试。
PS:全代码里多了 animation-timing-function 和 animation-fill-mode 属性的设置,前者可以让旗帜效果更好,后者是为了防止部分浏览器闪烁问题
javascript
<html>
<head><title>flag</title></head>
<body>
<div class="flag">
<div style="background-color: lightcoral;animation-delay: 0ms" />
<div style="background-color: lightsalmon;animation-delay: 100ms" />
<div style="background-color: lightgoldenrodyellow;animation-delay: 200ms" />
<div style="background-color: lightgreen;animation-delay: 300ms" />
<div style="background-color: lightcyan;animation-delay: 400ms" />
<div style="background-color: lightblue;animation-delay: 500ms" />
<div style="background-color: purple;animation-delay: 600ms" />
</div>
<style>
.flag{
display: flex;
padding: 15px;
}
@keyframes move{
from{
transform: translateY(-5px);
}
to{
transform: translateY(5px);
}
}
.flag div{
width: 15px;
height: 70px;
border-radius: 3px;
animation-name: move; /* 动画名称:move */
animation-duration:500ms; /* 动画速度:500毫秒 */
animation-iteration-count:infinite; /* 播放次数:无限*/
animation-direction: alternate;/* 播放方式:动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。 */
animation-timing-function: ease-in-out;/* 动画排列速度:动画以低速开始和结束 */
animation-fill-mode: backwards;/* 防止部分浏览器闪烁问题 */
}
</style>
</body>
</html>