最近我的项目中 Ant Design 接入比拟多,还是十分不错的。不晓得大家有没有发现这样的成果,在官网上,如果鼠标放在 Logo 上,字母 i
上的图标会不停的变动,来到后进行,放上去从新变动,算得上是一个小彩蛋(可能我之前没发现🤣),演示如下:
不过没发现也不意外,因为这个成果是 js 实现的,必须期待加载实现能力失效,而官网有时候又特地的慢,比方像这种还在加载的状况下,大概率是不会有以上的 hover
成果的
嗯,思考了一下,这种成果齐全能够用纯 CSS 来实现呀,实现老本又低,又能无效防止上述的加载问题,一起看看吧
一、CSS 实现原理
整个实现原理大抵如下
- 筹备一个蕴含所有小图标的素材
- 创立一个扭转背景地位的 CSS 逐帧动画
- 通过鼠标 hover 来管制动画运行
二、素材筹备
为了防止屡次申请,也为了不便创立动画,这里把所有小图标素材组合在一块(从官网另存下来的),就像以前的“雪碧图”一样,如下
假如 HTML 构造是这样的
<h1 class="logo">Ant Design</h1>
为了更好的语义化,这里的文字倡议保留,而后通过其余形式暗藏文字(比方透明度),能够将 logo 作为背景图片,而后可变动的小图标用伪元素生成(装饰性的元素都能够用伪元素来生成,保障 HTML 的整洁),CSS 如下
.logo{
width: 500px;
height: 100px;
position: relative;
color: transparent;
background: url('https://imgservices-1252317822.image.myqcloud.com/image/012420220165011/c0e82c29.svg') center/contain no-repeat;
cursor: pointer;
}
.logo::after{
content: '';
position: absolute;
width: 32px;
height: 32px;
background: url('https://imgservices-1252317822.image.myqcloud.com/image/012420220165415/b0005044.svg') 0 / cover no-repeat;
right: 113px;
top: -18px;
}
动态布局就算进去了
二、CSS 逐帧动画
而后是动画,只须要利用 CSS 动画函数中的 steps() 性能符,就能够实现逐帧动画
首先定义一个关键帧,扭转背景地位就行了
@keyframes random {
to {background-position: 100%;}
}
这里小图标总共有 11 张,相互之间的变动就是 10 步,所以动画设置如下
.logo::after{
/* 其余款式 */
animation: random 1s steps(10) infinite;
}
这样就失去了一个有限循环的逐帧动画
三、CSS 动画的暂停与运行
默认状况下,CSS 动画是默认运行的,然而当初的需要是,只有鼠标 hover
下来才会动起来。
可能有同学会这样做,默认状况下没有动画,hover 的时候创立动画,如下
.logo::after{/* 默认无动画 */}
.logo:hover::after{animation: random 1s steps(10) infinite;
}
然而这样做会有两个问题:
- 每次实时创立动画会有更多的性能耗费
- 每次鼠标来到后地位就还原成初始状态了
因而,这种形式并不可取
除了上述形式能够管制动画运行之外,还能够通过 animation-play-state
被动设置暂停,如下
.logo::after{
/* 其余款式 */
animation: random 1s steps(10) infinite;
animation-play-state: paused; /* 动画暂停 */
}
这样下来,默认就不会动了,而后在 hover
的时候“运行”就行了
.logo:hover::after{animation-play-state: running; /* 动画运行 */}
成果如下
四、指定初始地位
当初默认是小图标是第一个,如果想指定另外一个,比方❤
这种状况如何解决呢
首先咱们想到,能够手动扭转背景地位就行了,❤ 在第 8 个,所以
.logo::after{
/* 其余款式 */
background-position: -224px; /* 32 * 7 */
}
成果如下
这样下来,问题更多,因为扭转了动画的起始地位,动画从第 8 个的中央静止到最右侧,右边的都不通过了,step 也须要从新调整。
除了这种形式,还能够通过动画的“负提早”来实现,给动画增加一个负的提早后,动画会提前静止到将来地位。
比方这里想指定到将来第 7 帧的地位,就能够提早负的总静止时长的 7/ 10,实现如下
.logo::after{
/* 其余款式 */
animation-delay: -.7s; /* 7 / 10 * 1s*/
}
这样就不会影响原有的动画了,完满实现
残缺代码能够拜访:Ant Design Logo (codepen.io)
附上残缺代码(最近 codepen 貌似不太稳固)
.logo{
width: 500px;
height: 100px;
position: relative;
color: transparent;
background: url('https://imgservices-1252317822.image.myqcloud.com/image/012420220165011/c0e82c29.svg') center/contain no-repeat;
cursor: pointer;
}
.logo::after{
content: '';
position: absolute;
width: 32px;
height: 32px;
background: url('https://imgservices-1252317822.image.myqcloud.com/image/012420220165415/b0005044.svg') 0 / cover no-repeat;
right: 113px;
top: -18px;
animation: random 1s -.7s steps(10) infinite;
animation-play-state: paused;
}
.logo:hover::after{animation-play-state: running;}
@keyframes random {
to {background-position: 100%;}
}
五、总结和阐明
下面就是针对 Ant Design 官网 Logo 成果的 CSS 实现,代码量非常少,而且也防止了 js 未加载实现时的问题,体验更好,上面简略总结一下
- CSS 渲染是及时的,只有页面可见,就不会影响 CSS 交互
- 逐帧动画能够通过 CSS 动画 中的 step() 函数实现
- CSS 动画能够主动运行,也能够手动暂停
- 通过设置负的延时,能够让 CSS 动画提前运行
当然,CSS 的长处还不只这些,关上 Ant Design 控制台,让我有点解体的是,竟然是一直更换 svg
链接实现的,如果始终放在 Logo 上就会源源不断的申请图片,小图标也会呈现“闪动”的状况
这个申请量就有点惊人了。如果有负责 Ant Design 官网的小伙伴看到这里,是不是能够优化一下呢?
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤