上面效果可以概括为:
- 鼠标未停留时:button背景与body保持一致(以黑色为例),文字为蓝色,同时button四周一条蓝色的线条一直围绕button旋转
- 鼠标停留时:button按钮背景变为蓝色,其中文字变为黑色,同时产生阴影、倒影
根据效果图可以得出实现的一些思路:
- 背景颜色的变化使用hover就可以实现
- 难点在于四周的线条
- 这里海轰的解决办法是分为上下左右四条线,赋予每一条线一个动画,通过延时达到类似一条线的效果
这里使用的蓝色:
- 蓝色:#03e9f4
HTML
Document Haihong Pro
CSS
html,body{ margin: 0; height: 100%; } body{ display: flex; justify-content: center; align-items: center; background: black; } .btn{ width: 300px; height: 120px; font-family: 'Lato', sans-serif; font-weight: 500; font-size: 36px; color: #03e9f4; /* 字符间的距离 */ letter-spacing: 2px; background: transparent; border: none; position: relative; overflow: hidden; transition: 0.5s; } .btn:hover{ background: #03e9f4; color: black; box-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 200px #03e9f4; /* 倒影 */ -webkit-box-reflect:below 1px linear-gradient(transparent, #0005); } .btn span{ position: absolute; content: ''; } .btn span:nth-child(1){ top: 0; left: 0; width: 100%; height: 4px; animation: animate1 1s linear infinite; background: linear-gradient(90deg,transparent,#03e9f4); } @keyframes animate1{ 0%{ left: -100%; } 50%,100%{ left: 100%; } } .btn span:nth-child(2){ top: -100%; right: 0; width: 4px; height: 100%; background: linear-gradient(180deg,transparent,#03e9f4); animation: animate2 1s linear infinite; animation-delay: 0.25s; } @keyframes animate2{ 0%{ top: -100%; } 50%,100%{ top: 100%; } } .btn span:nth-child(3){ bottom: 0; right: 0; width: 100%; height: 4px; background: linear-gradient(270deg,transparent,#03e9f4); animation: animate3 1s linear infinite; animation-delay: 0.55s; } @keyframes animate3{ 0%{ right: -100%; } 50%,100%{ right: 100%; } } .btn span:nth-child(4){ bottom: -100%; left: 0; width: 4px; height: 100%; background: linear-gradient(360deg,transparent,#03e9f4); animation: animate4 1s linear infinite; animation-delay: 0.75s; } @keyframes animate4{ 0%{ bottom: -100%; } 50%,100%{ bottom: 100%; } }原理解释
这里还是主要讲讲四周线条的动画效果吧
四条线条的初始位置如下:
注:
- 这里将颜色改为红色,线条宽度为20px,便于观察
- 这里说的初始位置是指动画开始时的初始位置
以一条线条(第一条)的动画为例
其css设置为:绝对定位 position:absolute top=0 left=0
初始位置如图:
第一条线条动画需要实现的效果
- 线条头部从button最左端开始移动
- 平行向右移动
- 最终停下位置为:线条尾部到达button最右端
最初位置:
最终位置:
根据上述思路,编写动画代码
.btn span:nth-child(1){ top: 0; left: 100%; width: 100%; height: 20px; animation: animate1 1s linear infinite; background: linear-gradient(90deg,transparent,red); } // 动画:从左到右 @keyframes animate1{ 0%{ left: -100%; } 50%,100%{ left: 100%; }
效果如下:
我们的需求是:线条只需要在button区域进行动画,其他区域用户不可见
解决办法也很简单:button中设置:overflow: hidden;
效果如下:
同理,再分别对其他三条边进行设置就可以了
第二条线效果:
第三条线效果:
第四条线条效果:
疑点详解疑点1
估计细心的小伙伴会注意到
- 动画animate1延迟为0
- 动画animate2延迟为0.25s
- 动画animate3延迟为0.5s
- 动画animate4延迟为0.75s
为什么会这样设置呢?
emmm 这里就说说海轰自己的理解吧
首先,我们将每一个动画的时间都位置为了 1s
为了达到连贯的效果,也就是:
- 线条1头部到达button最右端时,线条2头部恰好从button最上端向下开始移动
- 线条2头部到达button最下端时,线条3头部恰好从button最右端向左开始移动
- 线条3头部到达button最左端时,线条4头部恰好从button最下端开始向上移动
- 线条4头部到达button最上端时,线条1头部恰好从button最左端开始向右移动
- 依次循环
从上述的效果描述中,我们可以得知,从线条4头部到达最上端时,线条1恰好又进行第二次动画
也就是每次动画间隔了1s
每条线运行的时间又相同,所以在button上移动的时间也是相同的
均为 1s/4=0.25s
也就是说:线条1头部从button最左端到最右端,耗时0.25s
简单的理解:
每隔1s线条1就要出发一次
为了得到连贯效果,必须要求1s之内,其他3条线都跑完button三条边
而跑完每一条边需要的时间又是一样的(这个是通过ambition设置的)
从而得出 每一条边需要 1s/4 = 0.25s
此时,线条2才开始动画,也就需要延时0.25s
同理,线条3、4 的延时也就累计就可以了
疑点2
为什么动画设置是0%-50%呢
@keyframes animate1{ 0%{ left: -100%; } 50%,100%{ left: 100%; } }
从疑点1的解答中,我们可以发现,每条线在button边运行的时间只能为0.25s
线条从开始到结束,需要耗时 1s(也就是从0%-100%)
/* 假设这样设置 */ @keyframes animate1{ 0%{ left: -100%; } 100%{ left: 100%; } }
因为移动速度为匀速(动画属性设置了)
所以到50%需要耗时0.5s
也就是说:线条1运行在button上的时间为:0.5s
这与我们需要的0.25s就有区别
那么需要怎么办呢?
哈哈,这里我们将动画属性修改一下:
@keyframes animate1{ 0%{ left: -100%; } 50%,100%{ left: 100%; } }
啥意思呢?
简单理解就是只用了一半的时间(0.5s)就从开始状态运行到了最终状态(0%-100%)
那么从0%-50%就只需要0.25s了
注:这里海轰说的估计不是很好理解,但是自己心里知道咋回事,不太会描述,不懂的小伙伴可以查查ambition的介绍
符合要求!