(给前端瓶子君加星标)
转自:CodingStarup
juejin.cn/post/6908565208596217863
大家好,我是 Steven。
虽然我不打机,但我都知道 赛博朋克 2077 这个游戏,在它的网页上,有一个 Available Now 的按钮,当游标移到它之上的时候,会有一个好像故障的毛刺效果。
![](https://i-blog.csdnimg.cn/blog_migrate/069ca14bc5e71b6ba8f055bfc00ec058.png)
这一期,我们就会模仿并且实现这个效果。
这个教程的视频版在
https://www.bilibili.com/video/BV15A411s7cX
编写 HTML 代码
打开 CodePen 编辑器 ( codepen.io ),在 HTML 的部份加入 <button>
标签,按钮的标题是 AVAILABLE NOW。
![](https://i-blog.csdnimg.cn/blog_migrate/48f82f977441e08bd5f19946da15db00.png)
CSS 的部分
然后到 CSS 的部份,加入 body
标签,用 Flexbox 的方法将内容设定为上下左右置中。然后背景颜色,设定为黄色,加入 button
选择器,宽度设定为 380px
,而高度设定为 86px
,文字大小设定为 36px
。
![](https://i-blog.csdnimg.cn/blog_migrate/3278791e0674b7efbfa17665a62d1704.png)
然后我想换一种字型,到 Google Font 网站上,选择了 Bebas Neue 这个字型,将载入字体的代码贴到 HTML 内,然后将 CSS 字体的设定套用到 button 选择器内。
![](https://i-blog.csdnimg.cn/blog_migrate/b5f4c0035aa07e1a486e8e787dc74d9e.png)
好了,将左下角变为斜角可以怎样做呢,一开始我想用 clip-path
去实现,但我想了又想,好像有一种更简单的方法,就是透过 linear-gradient
设定背景图片了。设定 background
是 linear-gradient()
,角度设定为 45deg
,然后由透明色的 50%
,切换为红色的 50%
,这样 50%
前的部份就会透明,而 50%
后的部份就是红色,做到一个颜色分割的效果。
那我们要将红色的部份占大多数,只需要将 50%
改为 5%
,就可以做到左下的斜角了。
![](https://i-blog.csdnimg.cn/blog_migrate/e841516913b95f533d1aa67249fbf239.png)
然后框线设定为 0
,文字颜色设定为白色,letter-spacing
字距设定为 3px
,然后我觉得文字的上下有点不对齐,设定 line-height
是 88px
,这样就好一点了。
然后设定右边的亮蓝色边,将 box-shadow
设定为 6px 0px 0px #00E6F6
,再将 outline
设定为 transparent
,这样当点击按钮的时候,就不会有浏览器预设的按钮边框了。
![](https://i-blog.csdnimg.cn/blog_migrate/153d001444c2ea22e0b0916d904cbe26.png)
现在按钮的样式大致上都实现了,那么怎样实现当游标移到它之上的时候,出现的那些毛刺效果呢?我们先在这个按钮上,重叠一个一模一样的按钮 要实现这一步,我会使用 Pseudo 伪类选择器。
实现变色层
加入 button::after
选择器,将 content
设定为 AVAILABLE NOW
,然设 display
设定为 block
,position
设定为 absolute
,当这里的 position
设定为 absolute
,我们就回到 button
选择器里面,将 position
设定为 relative
,这样它才可以根据按钮去定位,然后上下左右,都设定为 0
,其余样式都与原来的按钮相同,所以在 button
选择器后面,加入逗号,button::after
就可以了。
![](https://i-blog.csdnimg.cn/blog_migrate/47370bf69dd1d2ef7ead39032ee09a10.png)
这个叠在上面的按钮,我们会透过 clip-path()
,裁剪其中一些部份出来,然后配合 transform
进行一些位移,再透过 animation
去达到动画的效果。所以我们会先在这一层做好变色的效果,首先是左下的斜角,会突显一些蓝色出来,将透明色的比例改为 3%
,然后在中间加入一个亮蓝色,由 3%
至 5%
,然后就是中间的文字,加入 text-shadow
文字阴影,在左边加入一个黄色,右边加入一个蓝色,大致上就是这样了。
![](https://i-blog.csdnimg.cn/blog_migrate/10b9b1eb08a17884aabf0f08c484c1e1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6695e8fb241fc5dabf3077c13823bbc5.png)
图形切割
下一步就是处理图形分割的部份,加入 clip-path
,套用 inset()
,里面的设定值有 4 个,分别代表上右下左,即是要向内缩小多少的意思。先设定为 80% \-6px 0 0
,右边设定为 -6px
的原因是,右边有一个亮蓝色的边框,由于它不计算在容器的范围内,所以要将右边设定为负数。
由于现在是完全重叠的状态,切割了也不明显,加入 transform: translate(-20px, 10px)
稍为移开一点,就可以清楚看到正在切割的是哪个部份了。先将这个切片储存到 CSS 变数中,名为 slice-1
。
![](https://i-blog.csdnimg.cn/blog_migrate/67d66f6bf0d64f90c87e43731c4e5583.png)
第二个切片的数值是 50% \-6px 30% 0
,储存为 slice-2
。第三个切片的数值是 10% \-6px 85% 0
,是上面的部份,储存为 slice-3
。第四个切片的数值是 40% \-6px 43% 0
,都是文字的部份,储存为 slice-4
。再做多一个切片就好了,第五个的数值是 80% \-6px 5% 0
,是下方的部份,储存为 slice-5
。
再新增一个预设值,50% 50% 50% 50%
,储存为 slice-0
,那我们这里 clip-path
的设定值改为 var(--slice-0)
,并且将 transform
移除就可以了。
![](https://i-blog.csdnimg.cn/blog_migrate/7c84631ee62c5724e3db86fe5e2e5e09.png)
其实这里所做的切片的位置和数量是挺随机的,大家可以根据想达到的效果自行更改数值。
动画制作
最后,制作动画的部份,新增 @keyframes glitch
定义一个动画名为 glitch
,这里我分为 11 个部份,0%,10%,20%
,如此类推,一直至到 100%
。然后在每一个部份都设置 clip-path()
和 transform()
,clip-path()
就随机套用一个切片,而 transform()
就定义一些随机值,稍为移动一下就可以了。
@keyframes glitch {
0% {
clip-path: var(--slice-1);
transform: translate(-20px, -10px);
}
10% {
clip-path: var(--slice-3);
transform: translate(10px, 10px);
}
20% {
clip-path: var(--slice-1);
transform: translate(-10px, 10px);
}
30% {
clip-path: var(--slice-3);
transform: translate(0px, 5px);
}
40% {
clip-path: var(--slice-2);
transform: translate(-5px, 0px);
}
50% {
clip-path: var(--slice-3);
transform: translate(5px, 0px);
}
60% {
clip-path: var(--slice-4);
transform: translate(5px, 10px);
}
70% {
clip-path: var(--slice-2);
transform: translate(-10px, 10px);
}
80% {
clip-path: var(--slice-5);
transform: translate(20px, -10px);
}
90% {
clip-path: var(--slice-1);
transform: translate(-10px, 0px);
}
100% {
clip-path: var(--slice-1);
transform: translate(0);
}
}
复制代码
keyframes
的部份设定好了,加入 button:hover::after
选择器,当游标移到按钮之上的时候,触发动画,设定 animation
,时间是 1
秒,动画名称是 glitch
。试试看,基本上是可以了。
![](https://i-blog.csdnimg.cn/blog_migrate/485d6b91e833aaf2ed02f93c3d20dcfc.png)
不过,这个是故障的效果呢,动画怎么会这么流畅,我们为它加一个设定,让它变得十分卡顿。设定 animation-timing-function 为 steps(2, end)
,数字越小,就越卡顿,大家可以试试。
我们来看看这个案例的完成效果
![](https://i-blog.csdnimg.cn/blog_migrate/069ca14bc5e71b6ba8f055bfc00ec058.png)
以上,就是要介绍的全部内容。
最后
欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
欢迎关注「前端瓶子君」,回复「算法」,加入前端算法源码编程群,每日一刷(工作日),每题瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
![](https://i-blog.csdnimg.cn/blog_migrate/fd3821b7270d81677c24152b1a85e8c5.png)
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持