经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
抖音抖一抖-SVG和CSS视觉故障艺术小赏
来源:cnblogs  作者:wphmoon  时间:2019/10/10 8:51:25  对本文有异议

故障艺术,英文名称叫glitch,在很多赛博朋克作品中经常看到,其实就是故意表现一种显示设备的小故障效果,抖音的图标其实就是这种的效果,我们看下这个图标

这个图标中的红色和蓝色的偏移其实就是一种故障艺术,看到这个,我就能想到早年我家还没有有线电视时,摇天线对电视信号的场景,信号一差就是对着电视一阵拳打脚踢,现在看到这种艺术效果颇为怀念。

某甲:为啥我没遇到过这种场景?

我:你把手里的平板扔地上就能看到了。

某甲:(土豪动作完成)我摔了,咋还没看到呢

我:我就打个比方,你何必当真...

某甲:我一定要看到!

我:要不你再跺几脚...

----------------------------------------我是打算开始的分割线------------------------------------------

我们先来实现一个动态的抖音故障效果,首先我们要有一个干净的抖音图标,我是从阿里巴巴矢量图标库找的,因为它家支持SVG格式,得到的SVG代码是这样的。

  1. <svg id="douyin" t="1570181112474" class="icon" viewBox="0 0 1024 1024" version="1.1"
  2. xmlns="http://www.w3.org/2000/svg" p-id="2916" width="128" height="128">
  3. <path
  4. d="M937.386667 423.850667a387.84 387.84 0 0 1-232.874667-77.824v352.341333C704.512 878.250667 565.930667 1024 394.922667 1024S85.333333 878.250667 85.333333 698.368c0-179.882667 138.581333-325.632 309.589334-325.632 17.066667 0 33.706667 1.450667 49.92 4.266667v186.624a131.754667 131.754667 0 0 0-48.64-9.216c-76.288 0-138.154667 65.024-138.154667 145.322666 0 80.213333 61.866667 145.322667 138.24 145.322667 76.202667 0 138.069333-65.109333 138.069333-145.322667V0h172.714667c0 134.485333 103.68 243.541333 231.594667 243.541333v180.309334h-1.28"
  5. p-id="2917"></path>
  6. </svg>

看到的图形是这样子的

注意,在SVG的代码里面是没有设置颜色的,图片里面的黑色是为了让大家看清楚。我们先把白色,蓝色和红色的三层抖音图标先显示出来,代码如下:

  1. <use xlink:href="#douyin" x="0%" y="10%" class="douyin1" />
  2. <use xlink:href="#douyin" x="0%" y="10%" class="douyin2" />
  3. <use xlink:href="#douyin" x="0%" y="10%" class="douyin" />
  1. /* 白色 */
  2. .douyin {
  3. fill: #fff;
  4. }
  5. /* 蓝色 */
  6. .douyin1 {
  7. fill: #25f4ee;
  8. }
  9. /* 红色 */
  10. .douyin2 {
  11. fill: #fe2c55;
  12. }

分别填上了白色,红色和蓝色,在SVG里面,后面的会覆盖前面的,所以把白色放在最前面,因为现在三者的位置是重叠的,所以只能看到白色的。

我们再设置白色的动画效果

  1. @keyframes glitch1 {
  2. 0% {
  3. transform: none;
  4. opacity: 1;
  5. }
  6. 7% {
  7. transform: skew(-2.5deg, -0.9deg);
  8. opacity: 0.75;
  9. }
  10. 10% {
  11. transform: none;
  12. opacity: 1;
  13. }
  14. 27% {
  15. transform: none;
  16. opacity: 1;
  17. }
  18. 30% {
  19. transform: skew(1.8deg, -0.1deg);
  20. opacity: 0.75;
  21. }
  22. 35% {
  23. transform: none;
  24. opacity: 1;
  25. }
  26. 52% {
  27. transform: none;
  28. opacity: 1;
  29. }
  30. 55% {
  31. transform: skew(-1deg, 1.2deg);
  32. opacity: 0.75;
  33. }
  34. 60% {
  35. transform: none;
  36. opacity: 1;
  37. }
  38. 72% {
  39. transform: none;
  40. opacity: 1;
  41. }
  42. 75% {
  43. transform: skew(0.4deg, -1deg);
  44. opacity: 0.75;
  45. }
  46. 80% {
  47. transform: none;
  48. opacity: 1;
  49. }
  50. 100% {
  51. transform: none;
  52. opacity: 1;
  53. }
  54. }

白色的动画效果很小,因为我只做了一些轻微的倾斜效果,感觉画面在抖动,用的是 transform: skew()。transform是css的一个属性,主要设置的是变形效果,这边用的skew是实现倾斜效果。另外还用opacity做了些透明度的处理,用来表现信号故障时的亮度变化。

我们接着设置蓝色图标的动画效果:

  1. @keyframes glitch2 {
  2. 0% {
  3. transform: none;
  4. opacity: 0.25;
  5. }
  6. 7% {
  7. transform: translate(-4px, -6px);
  8. opacity: 0.5;
  9. }
  10. 10% {
  11. transform: none;
  12. opacity: 0.25;
  13. }
  14. 27% {
  15. transform: none;
  16. opacity: 0.25;
  17. }
  18. 30% {
  19. transform: translate(-7px, -4px);
  20. opacity: 0.5;
  21. }
  22. 35% {
  23. transform: none;
  24. opacity: 0.25;
  25. }
  26. 52% {
  27. transform: none;
  28. opacity: 0.25;
  29. }
  30. 55% {
  31. transform: translate(-5px, -2px);
  32. opacity: 0.5;
  33. }
  34. 60% {
  35. transform: none;
  36. opacity: 0.25;
  37. }
  38. 72% {
  39. transform: none;
  40. opacity: 0.25;
  41. }
  42. 75% {
  43. transform: translate(-4px, -6px);
  44. opacity: 0.5;
  45. }
  46. 80% {
  47. transform: none;
  48. opacity: 0.25;
  49. }
  50. 100% {
  51. transform: none;
  52. opacity: 0.25;
  53. }
  54. }

这里同样是使用transform变形,但用的效果是translate,官方的名称是2D转换,其实就是平移效果,可以在横向纵向做移动,我们看抖音的图标就知道,蓝色部分是在白色图标的左上方,所以设置的translate的值都是负数,这是左上方的平移。

红色部分类似,只是translate的值都是正数,表示时右下方的平移。代码如下:

  1. @keyframes glitch3 {
  2. 0% {
  3. transform: none;
  4. opacity: 0.25;
  5. }
  6. 7% {
  7. transform: translate(4px, 6px);
  8. opacity: 0.5;
  9. }
  10. 10% {
  11. transform: none;
  12. opacity: 0.25;
  13. }
  14. 27% {
  15. transform: none;
  16. opacity: 0.25;
  17. }
  18. 30% {
  19. transform: translate(7px, 4px);
  20. opacity: 0.5;
  21. }
  22. 35% {
  23. transform: none;
  24. opacity: 0.25;
  25. }
  26. 52% {
  27. transform: none;
  28. opacity: 0.25;
  29. }
  30. 55% {
  31. transform: translate(5px, 2px);
  32. opacity: 0.5;
  33. }
  34. 60% {
  35. transform: none;
  36. opacity: 0.25;
  37. }
  38. 72% {
  39. transform: none;
  40. opacity: 0.25;
  41. }
  42. 75% {
  43. transform: translate(4px, 8px);
  44. opacity: 0.5;
  45. }
  46. 80% {
  47. transform: none;
  48. opacity: 0.25;
  49. }
  50. 100% {
  51. transform: none;
  52. opacity: 0.25;
  53. }
  54. }

最后,把动画效果加到css类里面去,之前的css代码改成这样

  1. .douyin {
  2. fill: #fff;
  3. /*Animation*/
  4. animation: glitch1 3s infinite;
  5. }
  6. .douyin1 {
  7. fill: #25f4ee;
  8. animation: glitch2 3s infinite;
  9. }
  10. .douyin2 {
  11. fill: #fe2c55;
  12. animation: glitch3 3s infinite;
  13. }

动画效果设置成3秒,无限循环,最后的成品效果如下:

在线效果请移步codepen.io

---------------------------------------------还有高级效果的分割线----------------------------------------

上面实现的是模仿抖音官方图标的动态效果,但作为一个赛博朋克艺术家(是的,我都艺术家好几个星期了),我觉得这个效果虽然很符合抖音的气质,但离我想象中的高大上效果还有很大一段距离,我决定再加些效果,更加赛博朋克一些。

这里我要用上一个负责的svg的filter,代码如下:

  1. <filter id="filter">
  2. <feTurbulence type="turbulence" baseFrequency="0.01 0.15" numOctaves="2" seed="5" stitchTiles="stitch"
  3. result="turbulence" />
  4. <feColorMatrix type="saturate" values="30" in="turbulence" result="colormatrix" />
  5. <feColorMatrix type="matrix" values="1 0 0 0 0
  6. 0 1 0 0 0
  7. 0 0 1 0 0
  8. 0 0 0 150 -15" in="colormatrix" result="colormatrix1" />
  9. <feDisplacementMap in="SourceGraphic" in2="colormatrix1" scale="10" xChannelSelector="R" yChannelSelector="A"
  10. result="displacementMap" />
  11. </filter>

这是一个组合的filter效果,具体的分工如下:

  • feTurbulence是利用Perlin噪声函数创建了一个图像。它实现了人造纹理比如说云纹、大理石纹的合成,我之前做云朵的时候用的就是它。这里主要实现干扰信号的效果
  • feColorMatrix 基于转换矩阵对颜色进行变换,在这里可以把白、蓝、红的颜色混合,在三种颜色叠加的地方产生一种颜色互相干扰的效果
  • feDisplacementMap 实际上是一个位置替换滤镜,就是改变元素和图形的像素位置的。在这里,针对抖音的图标(SourceGraphic)和经过feColorMatrix /feTurbulence过滤器后的结果做位置变换,就等到了干扰效果的最终结果。

最后我们把这个filter加到动画效果里面,我们拿三个keyframe中的一个来看下代码,其他两个是一样的。

  1. @keyframes glitch1 {
  2. 0% {
  3. transform: none;
  4. opacity: 1;
  5. }
  6. 7% {
  7. transform: skew(-2.5deg, -0.9deg);
  8. filter: url(#filter);
  9. opacity: 0.75;
  10. }
  11. 8% {
  12. filter: none;
  13. }
  14. 10% {
  15. transform: none;
  16. opacity: 1;
  17. }
  18. 27% {
  19. transform: none;
  20. opacity: 1;
  21. }
  22. 30% {
  23. transform: skew(1.8deg, -0.1deg);
  24. filter: url(#filter);
  25. opacity: 0.75;
  26. }
  27. 31% {
  28. filter: none;
  29. }
  30. 35% {
  31. transform: none;
  32. opacity: 1;
  33. }
  34. 52% {
  35. transform: none;
  36. opacity: 1;
  37. }
  38. 55% {
  39. transform: skew(-1deg, 1.2deg);
  40. filter: url(#filter);
  41. opacity: 0.75;
  42. }
  43. 56% {
  44. filter: none;
  45. }
  46. 60% {
  47. transform: none;
  48. opacity: 1;
  49. }
  50. 72% {
  51. transform: none;
  52. opacity: 1;
  53. }
  54. 75% {
  55. transform: skew(0.4deg, -1deg);
  56. filter: url(#filter);
  57. opacity: 0.75;
  58. }
  59. 76% {
  60. filter: none;
  61. }
  62. 80% {
  63. transform: none;
  64. opacity: 1;
  65. }
  66. 100% {
  67. transform: none;
  68. opacity: 1;
  69. }
  70. }

filter: url(#filter) 这一句就是调用svg filter的语句。注意每调用一次这个,在后面都会加上这一句

  1. 31% {
  2. filter: none;
  3. }

这是为了让filter效果瞬间出现,瞬间消失,使得故障效果更加逼真。最终看到的效果如下:

在线效果请看codepen.io

源代码请看这里

原文链接:http://www.cnblogs.com/wphmoon/p/11644923.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号