这么炫酷的边框动画,原来是这样实现的
2024-08-07 09:09 阅读(246)

前言

最近在做大屏的项目,其中一些数据卡片,需要添加一些边框动画


倒腾来,倒腾去,写了下面这两种效果


接下来我们来看下实现这种效果

实现

转动的边框线

我们先实现这个效果

创建项目文件夹


mkdir light-card
cd code-review

创建 single.html 并用 vscode 打开

cd .>single.html
code ./

修改下single.html,清除下默认样式,加一点背景

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    body {
      background-color: black;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;;
    }
  </style>
</head>
<body>
  
</body>
</html>

接下来,我们实现一下这个卡片

添加body一个 div 作为卡片,并编写下简单的样式

边框线如何实现呢?


为了实现简单点,采用伪类去实现


.card::before, .card::after {
  content: "";
  position: absolute;
  top: -10px;
  left: -10px;
  right: -10px;
  bottom: -10px;
  border: 2px solid #ffffff;
  transition: all .5s;
  border-radius: 10px;
}

边框线有了,但不是一小一段的啊


这里就要采用一个神奇的 CSS属性 clip-path: inset(0 0 98% 0)

.card::before, .card::after {
    content: "";
    position: absolute;
    top: -10px;
    left: -10px;
    right: -10px;
    bottom: -10px;
    border: 2px solid #ffffff;
    transition: all .5s;
    border-radius: 10px;
    clip-path: inset(0 0 98% 0);
}

clip-path 使用裁剪方式创建元素的可显示区域


inset 是定义一个矩形,四个参数分别为 上侧、右侧、下侧和左侧向内的偏移量

clip-path: inset(0 0 98% 0)就是将下侧 90% 剪切掉,也就是红框的部分


根据这个CSS属性,实现一个动画剪切动画,先保留上侧,依次是右侧、下侧,依次循环

但是只有一条线啊


那是因为before、after 伪类重叠在一起了


给 after 重新加一个比before动画慢一半再执行的动画就好了

流光边框

这样的动画是怎么实现的?


我们来看下这个动画的本质

相信你也大概猜出了,这个动画就是通过遮挡最后旋转元素来实现的


接下来我们来实现下吧


创建 single.html 文件,并加入基本样式


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    body {
      background-color: black;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .card {
      width: 220px;
      height: 120px;
      color: #ffffff;
      text-align: center;
      line-height: 100px;
      font-size: 28px;
      border-radius: 10px;
      position: relative;
    }
  </style>
</head>
<body>
  <div class="card">
    流光边框
  </div>
</body>
</html>

创建最主要的旋转元素,为了方便还是使用伪元素

.card::before {
  content: '';
  position: absolute;
  left: -50%;
  top: -50%;
  width: 200%;
  height: 200%;
  border-radius: 10px;
  background-image: conic-gradient(transparent, #ffffff, transparent 30%);
  z-index: -2;
  animation: rotation 4s linear infinite;
}
@keyframes rotation {
  to {
    transform: rotate(360deg);
  }
}

采用 background-image 实现背景,且让元素绕中心旋转


z-index: 2 将旋转元素放到最后一层

把 .card 的背景颜色去掉,加上 overflow: hidden

最后,我们在这个两个元素的中间加一个黑色背景的元素,挡住里面的光

.card::after {
  content: '';
  position: absolute;
  --g: 4px;
  width: calc(100% - var(--g) * 2);
  height: calc(100% - var(--g) * 2);
  background: #000;
  left: var(--g);
  top: var(--g);
  border-radius: inherit;
  z-index: -1;
  opacity: 0.9;
}

至此,两个动画我们都实现了


小结

第一个动画,采用 clip-path属性动态剪切边框来实现


第二个动画,采用 遮挡旋转元素来实现