经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » CSS3 » 查看文章
【动画进阶】神奇的背景,生化危机4日食 Loading 动画还原
来源:cnblogs  作者:ChokCoco  时间:2023/10/11 16:11:50  对本文有异议

最近,在 Steam 玩一款老游戏(生化危机 4 重置版),其中,每当游戏转场的过程中,都有这么一个有趣的 Loading 动画:

整个效果有点类似于日食效果,中间一圈黑色,向外散发着太阳般的光芒。

本文,我们将尝试使用 CSS,还原这个效果。

整个效果做出来,类似于如下两个动画效果这样:

实现主体效果

其实,整个效果,去掉中间黑色的遮罩,是这个样子的:

所以,我们的目标就变成了,如何使用 CSS,实现上述这个图形效果。

角向渐变

到这里,思考一圈 CSS 中的各种属性,和这个图形能挂上钩的,几乎就只有角向渐变 conic-gradient 了。

我们可以利用多重角向渐变,试着画一个类似的图形 -- 从单个颜色到透明,再多次循环铺满 360° 的整个图形

  1. <div></div>
  1. body {
  2. background: #000;
  3. }
  4. div {
  5. width: 200vw;
  6. height: 200vh;
  7. background:
  8. repeating-conic-gradient(
  9. rgba(0, 136, 204, 0.77),
  10. rgba(150, 157, 100, 0.72) 2%,
  11. rgba(230, 247, 200, 0.82) 3%,
  12. transparent 4%,
  13. transparent 5%
  14. );
  15. }

我们随机设置了 conic-gradient() 中的颜色 A颜色 B颜色 C到透明的变化,可以得到这么一张图形:

注意,对于上面的颜色没有任何要求,随机设置都可以。

我们可以让这个图形旋转起来,简单加上一个旋转动画:

  1. div {
  2. animation: rotate 2s ease-in-out infinite;
  3. }
  4. @keyframes rotate {
  5. to {
  6. transform: rotate(1turn);
  7. }
  8. }

效果如下:

我们仔细观察一下,我们要的最终效果,其实要求边缘是毛刺状,而不是连续的图像:

这一步要怎么实现呢?其实也非常简单,我们只需要在原图像上,叠加一层从图像主色到黑色的径向渐变即可

我们可以借助伪元素实现这个叠加遮罩:

  1. div::before {
  2. content: "";
  3. position: absolute;
  4. inset: 0;
  5. background: radial-gradient(rgba(150, 157, 100, 0.32), rgba(0, 0, 0, 1) 45vmin, rgba(0, 0, 0, 1));
  6. }

这里我们实现了这么一个渐变:

  • radial-gradient(rgba(150, 157, 100, 0.32), rgba(0, 0, 0, 1) 45vmin, rgba(0, 0, 0, 1)):其核心就是实现了从某一个实体颜色(选取一个上面角向渐变图形用到的主要颜色)到黑色的一个径向渐变效果

这样,我们就将边缘改造的不那么突兀了!

效果如下:

设置多层背景

基于上述的原理及技巧,我们重新构思一下整个动画,上面只有一层角向背景的背景在运动。

那么,如果我们设置多层背景,并且,设置他们正向、反向一起运动呢?

我们来实现一个 4 层角向渐变背景的动画效果,并且使用最终我们想要的黄色为主题色,:

  1. <div class="g-container">
  2. <div class="g-circle g-circle1"></div>
  3. <div class="g-circle g-circle2"></div>
  4. <div class="g-circle g-circle3"></div>
  5. <div class="g-circle g-circle4"></div>
  6. </div>

完整的 CSS 代码如下:

  1. body{
  2. width: 100%;
  3. height: 100%;
  4. background: #000;
  5. }
  6. .g-container {
  7. position: absolute;
  8. width: 80vmax;
  9. height: 80vmax;
  10. top: 50%;
  11. left: 50%;
  12. transform: translate(-50%, -50%);
  13. .g-circle {
  14. position: absolute;
  15. inset: 0;
  16. border-radius: 50%;
  17. }
  18. .g-circle1 {
  19. background:
  20. repeating-conic-gradient(
  21. from 0deg at 50% 50%,
  22. transparent 0%,
  23. rgba(255, 230, 8, 0.69) 1%,
  24. transparent 6%
  25. );
  26. animation: 13s linear rotate infinite reverse;
  27. }
  28. .g-circle2 {
  29. background:
  30. repeating-conic-gradient(
  31. from 19deg at 50% 50%,
  32. transparent 0%,
  33. rgba(250, 240, 20, 0.78) 1.2%,
  34. rgba(250, 240, 20, 0.78),
  35. transparent 4.8%,
  36. transparent 7.6%
  37. );
  38. animation: 9s linear -2s rotate infinite;
  39. }
  40. .g-circle3 {
  41. background:
  42. repeating-conic-gradient(
  43. from 37deg at 50% 50%,
  44. transparent 0%,
  45. rgba(250, 240, 20, 0.78) 4%,
  46. transparent 7.9%,
  47. transparent 12%
  48. );
  49. animation: 17s linear rotate infinite reverse;
  50. }
  51. .g-circle4 {
  52. background:
  53. repeating-conic-gradient(
  54. from 103deg at 50% 50%,
  55. transparent 0%,
  56. rgba(250, 240, 20, 0.5) 5%,
  57. rgba(250, 240, 20, 0.27) 7%,
  58. transparent 12%
  59. );
  60. animation: 7s linear rotate infinite;
  61. }
  62. }
  63. @keyframes rotate {
  64. from {
  65. transform: rotate(0deg);
  66. }
  67. to {
  68. transform: rotate(359deg);
  69. }
  70. }

上面的代码,做了几件核心事情:

  1. 4 层背景重叠在一起
  2. 4 层背景设置不同的重复角向渐变图案 repeating-conic-gradient()
  3. 4 层背景两个顺时针旋转、两个逆时针旋转
  4. 动画的参数各不相同

这样,我们能得到这么一个效果:

此时,我们再在上述图形的基础上,叠加上一层遮罩 mask,将图案的边缘黑化:

  1. <div class="g-container">
  2. <div class="g-circle g-circle1"></div>
  3. <div class="g-circle g-circle2"></div>
  4. <div class="g-circle g-circle3"></div>
  5. <div class="g-circle g-circle4"></div>
  6. + <div class="g-circle g-mask"></div>
  7. </div>
  1. .g-container .g-mask {
  2. position: absolute;
  3. inset: -200px;
  4. background:
  5. radial-gradient(
  6. rgba(250, 240, 20, 0.2) 0,
  7. rgba(0, 0, 0, .8) calc(40vmax - 15vmax),
  8. #000 calc(40vmax - 5vmax),
  9. #000 100%
  10. );
  11. }

这里是一个比原容器稍微大的新容器(注意 inset: 200px),再设置从中心想外的径向渐变,最外层颜色为黑色。

这样,我们就能得到我们想要的效果了:

到这里,完整的代码,你可以戳这里:CodePen Demo -- Conic-gradient Pic

使用混合模式

当然,上述其实只是一种实现该图形动画的方式。

我们还可以借助混合模式,得到类似的效果。

这一次,我们将借助 SASS 的随机函数,随机生成不同的角向渐变背景,大致的代码如下:

  1. <div></div>
  1. @function randomNum($max, $min: 0, $u: 1) {
  2. @return ($min + random($max)) * $u;
  3. }
  4. @function randomConicGradient() {
  5. $n: 16 + random(16);
  6. $list: ();
  7. @for $i from 0 to $n {
  8. $list: $list, rgba(hsl(100, randomNum(250, 5, 10%), randomNum(1, 1, 1%)), randomNum(100, 0, .01));
  9. }
  10. @return conic-gradient($list, nth($list, 1));
  11. }
  12. body {
  13. overflow: hidden;
  14. }
  15. div {
  16. width: 100vw;
  17. height: 100vh;
  18. margin: 0;
  19. background:
  20. radial-gradient(hsl(9, randomNum(100, 75, 1%), randomNum(100, 75%, 1%)), black);
  21. &:before, &:after {
  22. position: absolute;
  23. top: 50%; left: 50%;
  24. margin: -100vmax;
  25. width: 200vmax;
  26. height: 200vmax;
  27. opacity: .5;
  28. animation: rotate randomNum(100, 25, .1s) ease-in-out infinite;
  29. content: '';
  30. }
  31. &:before { background: randomConicGradient(); }
  32. &:after {
  33. background: randomConicGradient();
  34. animation-duration: randomNum(100, 25, .1s);
  35. animation-direction: reverse;
  36. }
  37. }
  38. @keyframes rotate {
  39. to {
  40. transform: rotate(1turn);
  41. }
  42. }

上述的代码核心做了 3 件事:

  1. 元素本身设置了一个简单的从随机颜色到黑色的径向渐变
  2. 元素的两个伪元素借助 SASS 随机生成不同的角向渐变背景
  3. 两个伪元素做反向的旋转动画

这样,我们可以得到这么一种随机效果:

这里可能大家光看代码还是会有些费劲,我给大家再拆解一下,上面的图形,大致是由下述方式叠加而来(由于颜色都是随机生成的,所以更多的看每个结构实现了什么样的图形):

嘿,有点意思,不过别急,此时,我们再给两个伪元素,添加上一个混合模式 mix-blend-mode: overlay

  1. div {
  2. // ...
  3. &:before, &:after {
  4. mix-blend-mode: overlay;
  5. }
  6. }

这样,整个效果就变成了:

由于,颜色是随机的,刷新页面或者简单改变一些颜色参数,得到的效果就会很不一样,也有可能是这样的:

或者这样的:

借助混合模式,我们实现了更为酷炫的效果,上述的 DEMO,完整的代码在这里:CodePen Demo -- Animation conic-gradient

还原题图效果

好,到这里,我们再回归最开始我们希望实现的效果:

有了上面的铺垫,再看这个效果就没那么复杂了,本质就是在我们上述实现的图形中间,镂空一个黑色区域。

首先,我们借助上述铺垫的内容,实现这么一个图形:

接着,我们在内部,通过 mask,进行一个径向渐变的镂空即可,加上这么一句简单的代码:

  1. div {
  2. mask: radial-gradient(transparent, transparent 55%, #000 56%, #000);
  3. }

需要结合实现 background 的参数进行调试。

这样,我们就成功的实现一个类似的 Loading 图形:

完整的代码,你可以戳这里:CodePen Demo -- Animation conic-gradient & Mask

我们再看一个由 CodePen 上由 Yoav Kadosh 实现的另外一个原理类似的有意思的效果:

经由本文介绍的技巧,我们还可以演化出许多有意思的效果,读者朋友可以自行探索!

当然,我们不难看出,CSS 还是非常有意思的。

最后

好了,本文到此结束,希望对你有帮助 ??

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

原文链接:https://www.cnblogs.com/coco1s/p/17753942.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号