手把手教你实现一个小套环

225 阅读5分钟

前言

这次带大家来实现一个由 HTML 和 CSS 组合而成的效果,一个小套环的效果。话不多说,我们直奔主题。

效果预览

HTML部分

首先我们看到HTML部分,相关代码如下。

 <div class="circles">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      ...以下省略20span元素
    </div>

这里创建了一个包含了多个<span>元素的div容器,每个<span>元素可能被用于表示一个圆形或者圆点。

这里有一个div容器,具有circles类,用于将这些圆形/圆点相关的元素分组在一起,接着设置了很多个空的span元素,用于展示一系列的圆形或者圆点装饰元素。

CSS部分

看完HTML,紧接着我们看到CSS部分,首先是整体布局的一个样式,相关代码如下。

  body {
      margin: 0;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: black;
      overflow: hidden;
    }

margin: 0;表示移除了页面的默认边距。height: 100vh;则是将页面的高度设置为视口高度的 100%,确保整个页面填满视口。display: flex;表示使用弹性布局,这样子元素可以很容易地进行水平或垂直居中。align-items: center;justify-content: center;使得页面内容在水平和垂直方向上都居中显示。overflow: hidden;隐藏了页面的溢出内容,

然后是circle类的样式,相关代码如下。

  .circles {
      width: 60vmin;
      height: 60vmin;
      position: relative;
      margin-top: 20vmin;
      --particles: 30;
      animation: zoom 5s linear infinite;
    }
    @keyframes zoom {
      to {
        transform: scale(0.5) translateY(-50%);
      }
    }

这里定义了一个名为.circles的样式,并且创建了一个名为zoom的关键帧动画。在.circles中,width: 60vmin; height: 60vmin;设置了元素的宽度和高度,这里使用了vmin单位,它是视窗宽度或高度中较小的那个的相对单位,因此这会使得元素的大小基于视窗尺寸进行调整。position: relative;设置了元素的定位方式为相对定位。这将使得后代元素可以基于这个父元素进行定位。margin-top: 20vmin;设置了上外边距,同样也使用了vmin单位。--particles: 30;则是定义了一个 CSS 自定义属性,名为--particles,它的值为30。这个值可以在样式中后续被引用和调用,用于控制粒子的数量。

animation: zoom 5s linear infinite;创建了一个名为zoom的动画,它将在5秒内以线性时间函数进行无限循环。这个动画将会对元素应用一种缩放和平移的效果。 动画实现中的to定义了动画的最终状态,使得元素在动画结束时进行缩小并上移的效果。

接着是span元素的样式,相关代码如下。

   .circles span {
      position: absolute;
      width: 50%;
      height: 50%;
      background-color: white;
      border-radius: 50%;
      left: 25%;
      transform-origin: bottom center;
      --deg: calc(1turn / var(--particles) * (var(--n) - 1));
      animation: rotating 5s ease-in-out infinite;
      mix-blend-mode: difference;
    }
    @keyframes rotating {
      0% {
        transform: rotate(0deg);
      }
      50% {
        transform: rotate(var(--deg)) translateY(0);
      }
      100% {
        transform: rotate(var(--deg)) translateY(100%) scale(2);
      }
    }

这里定义了对.circles中的span元素应用旋转动画和混合模式以创造一个视觉效果。在.circles span中,position: absolute;span元素的定位方式设置为绝对定位,确保它们在父元素内精确定位。width: 50%; height: 50%;定义每个span元素的宽度和高度为父元素宽高的一半,使其成为圆形。background-color: white;设置了span元素的背景颜色为白色。border-radius: 50%;span元素的边框半径设置为50%,使其呈现为圆形。left: 25%;则是设置了span元素相对于父元素的水平偏移。这将使得它们在父元素中水平居中。transform-origin: bottom center;指定了旋转效果的原点位置为底部中心。--deg: calc(1turn / var(--particles) * (var(--n) - 1));通过CSS变量和计算函数calc(),动态计算了旋转的角度,根据--particles--n的值,来决定每个元素旋转的角度。mix-blend-mode: difference;应用了混合模式,将混合模式设置为difference,用于产生具有特殊视觉效果的元素混合。

animation: rotating 5s ease-in-out infinite;创建了一个名为rotating的动画,使每个元素进行旋转。该动画具有5秒的时间,以及缓入缓出的时间函数,并进行无限循环。在0% 时,元素的初始状态是不进行旋转的,在50% 时,元素逐渐旋转至--deg的角度,并向上平移,在100% 时,元素旋转至--deg的角度,向上平移至100% 的位置,并放大为原来的两倍。

最后是每个span的样式处理,相关代码如下。

  .circles span:nth-child(1) {
      --n: 1;
    }
    .circles span:nth-child(2) {
      --n: 2;
    }
    .circles span:nth-child(3) {
      --n: 3;
    }
    .circles span:nth-child(4) {
      --n: 4;
    }
    .circles span:nth-child(5) {
      --n: 5;
    } 

.circles span中使用了:nth-child()选择器来为每个span元素设置--n自定义属性的值。这个自定义属性被应用到之前定义的rotating动画中,用于确定每个元素在动画中的旋转顺序。每个span元素通过--n自定义属性表示了它们在动画中的顺序。这种用法允许为每个span元素动态指定不同的旋转角度,以便在整个视觉效果中创建不同的运动感。

总结

以上就是整个效果的实现过程了,纯 CSS 实现,代码简单易懂。另外,感兴趣的小伙伴们还可以在现有基础上发散思维,比如增加点其他效果,或者更改颜色等等。关于该效果如果大家有更好的想法欢迎在评论区分享,互相学习。最后,完整代码在码上掘金里可以查看,如果有什么问题大家在评论区里讨论~