css实现扫描动态波效!

CSS实现扫描动态波效的方法

最近业务场景需要实现一个扫描状态的动效(波纹渐变动效),顺利上线后,在这里将完整的实现过程和大家分享一下。 下面是最终实现:

下面让我们一起看下,这样的动效是怎样实现的吧~

一、实现中间的动效

image.png

这部分由5个圆构成,主要利用css的animation、Transform、scale、opacity等属性实现。

具体实现

5个圆以及动效

1.核心圆渐变

最中间的橙色圆背景使用渐变色,linear-gradient() 函数用于创建一个表示两种或多种颜色的线性渐变

background: linear-gradient(direction, color-stop1, color-stop2, ...);
描述
direction用角度值指定渐变的方向(或角度)。
color-stop1, color-stop2, ...指定渐变的起止颜色

实现橙色渐变:linear-gradient(90deg,rgba(255,195,139,1.000) ,rgba(255,148,86,1.000))

image.png

2.圆的动态扩散

外层的四个圆,使用animation、Transform、scale、opacity来共同实现扩散、渐隐的动画效果。

1.animation-name 作为CSS 属性,可以指定一个或多个 @keyframes at-rule 的名称,这些 at-rule 描述了要应用于元素的动画。多个 @keyframes at-rule 以逗号分隔的名称列表的形式指定。如果指定的名称不匹配任何 @keyframes at-rule,则不会对任何属性进行动画处理。

animation: name duration timing-function delay iteration-count direction;
描述
animation-name规定需要绑定到选择器的 keyframe 名称。
animation-duration规定完成动画所花费的时间,以秒或毫秒计。
animation-timing-function规定动画的速度曲线。
animation-delay规定在动画开始之前的延迟。
animation-iteration-count规定动画应该播放的次数。
animation-direction规定是否应该轮流反向播放动画。
animation-fill-mode规定动画在执行时间之外应用的值。
animation-play-state规定动画是正在运行还是暂停。
 animation-name: circleChange1;
 @keyframes circleChange1{
  0%{transform: scale(1);opacity: 1;}
  25%{transform: scale(1);opacity: 0.75;}
  50%{transform: scale(1);opacity: 0.5;}
  75%{transform: scale(1);opacity: 0.25;}
  100%{transform: scale(1);opacity: 0.75;}
}

通过 @keyframes 规则,可以创建动画。原理是将一套 CSS 样式逐渐变化为另一套样式。 在动画过程中,可以多次改变这套 CSS 样式。 以百分比来规定改变发生的时间,或者通过关键词 "from" 和 "to",等价于 0% 和 100%。 0% 是动画的开始时间,100% 动画的结束时间。

2.Transform属性应用于元素的2D或3D转换。这个属性允许你将元素旋转,缩放,移动,倾斜等。 transform: none|transform-functions;

描述
none定义不进行转换。
translate(x,y)定义 2D 转换。
translate3d(x,y,z)定义 3D 转换。
translateX(x)定义转换,只是用 X 轴的值。
translateY(y)定义转换,只是用 Y 轴的值。
translateZ(z)定义 3D 转换,只是用 Z 轴的值。
scale(x[,y]?)定义 2D 缩放转换。
scaleX(x)通过设置 X 轴的值来定义缩放转换。
scaleY(y)通过设置 Y 轴的值来定义缩放转换。
scaleZ(z)通过设置 Z 轴的值来定义 3D 缩放转换。

想要实现圆若隐如现的效果,则需要控制圆的透明度opacity。

image.png

整体代码:

html部分
    <div class="circleBox">
      <div class="circle">
          <div class="scanning">
            <div>扫描中...</div>
            <div>80%</div>
          </div>
      </div>
      <div class="circleOne"></div>
      <div class="circleTwo"></div>
      <div class="circleThree"></div>
      <div class="circleFour"></div>
    </div>
    
 css部分
     .circleBox {
      position: relative;
      width: 250px;
      height: 180px;
  }
  .circle {
      background: linear-gradient(90deg,rgba(255,195,139,1.000) ,rgba(255,148,86,1.000));
      border-radius: 50%;
      position: absolute;
      z-index: 99;
      width: 140px;
      height: 140px;
      top: 26px;
      left: 27px;
      color: #ffffff;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      cursor: pointer;
  }
  .circleOne  {
      background: #fbe4d4;;
      border-radius: 50%;
      position: absolute;
      z-index: 88;
      animation-name: circleChange1;
      width: 190px;
      height: 190px;
      animation-delay: 1s;
  }
  .circleTwo  {
      border: 1px solid #f19b5d ;
      border-radius: 50%;
      position: absolute;
      z-index: 77;
      animation-delay: 2s;
      animation-name: circleChange2;
  }
  .circleThree  {
      border: 1px solid #f8b283 ;
      border-radius: 50%;
      position: absolute;
      z-index: 66;
      animation-delay: 3s;
      animation-name: circleChange3;
  }
  .circleFour  {
      border: 2px dotted #f3ac79 ;
      border-radius: 50%;
      position: absolute;
      animation-delay: 4s;
      z-index: 55;
      animation-name: circleChange4;
  }
  .circleTwo, .circleThree, .circleFour  {
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
      width: 190px;
      height: 190px;
  }

  @keyframes circleChange{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange1{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1);opacity: 0.75;}
      50%{transform: scale(1);opacity: 0.5;}
      75%{transform: scale(1);opacity: 0.25;}
      100%{transform: scale(1);opacity: 0.75;}
  }
  @keyframes circleChange2{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange3{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange4{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
   
   

二、左右两侧扩散动效

1.左右两侧,分别由两个半圆组成

这个视觉上的半圆,本质上是一个圆的一半(控制width,height的值来决定弧度),通过控制background,让圆从左到右粉色渐变为白色,需要特别注意的是,如果我们的扫描动效背景不是白色,那么需要处理渐变为从粉色到透明:

linear-gradient(90deg, rgb(255, 237, 227, 0.6), rgb(255, 255, 255, 0.01), rgb(255, 255, 255, 0.01));

image.png

如果不处理的话,会出现这种情况:

image.png

2.控制半圆左右扩散和渐隐

和核心圆的实现类似,通过animation实现动画效果,animation-delay设置不同的值,控制动态波动

  animation-name: outLeftAnimation;
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-delay: 3
  @keyframes outLeftAnimation{
    0%{left: 30px;opacity: 0.05;}
    50%{left: -5px;opacity: 1;}
    100%{left: -30px;opacity: 0.05;}
  }

到目前为止,我们可以实现这样的效果啦 

image.png

我们也可以在边线上,挂上一些扫描文案:

<div class="ballAll ballEight">
  <div class="ballEightText">扫描点一</div>
</div>
.ballEight{
   top: 31px;
   position: absolute;
   left: 30px;
}
.ballEightText{
   width: 70px;
   margin-top: 10px;
   margin-left: -23px;
}

    

这就是最终效果啦~ 

image.png

看看动起来的效果

tutieshi_640x344_5s.gif

三、全部代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>扫描动效</title>
<style type="text/css">
  .circleBox {
      position: relative;
      width: 250px;
      height: 180px;
  }

  /* 扩散动画 */
  .circle {
      background: linear-gradient(90deg,rgba(255,195,139,1.000) ,rgba(255,148,86,1.000));
      border-radius: 50%;
      position: absolute;
      z-index: 99;
      width: 140px;
      height: 140px;
      top: 26px;
      left: 27px;
      color: #ffffff;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      cursor: pointer;

  }
  .circleOne  {

      background: #fbe4d4;;
      border-radius: 50%;
      position: absolute;
      z-index: 88;
      animation-name: circleChange1;
      width: 190px;
      height: 190px;
      animation-delay: 1s;
  }
  .circleTwo  {

      border: 1px solid #f19b5d ;
      border-radius: 50%;
      position: absolute;
      z-index: 77;
      animation-delay: 2s;
      animation-name: circleChange2;
  }
  .circleThree  {

      border: 1px solid #f8b283 ;
      border-radius: 50%;
      position: absolute;
      z-index: 66;
      animation-delay: 3s;
      animation-name: circleChange3;
  }
  .circleFour  {

      border: 2px dotted #f3ac79 ;
      border-radius: 50%;
      position: absolute;
      animation-delay: 4s;
      z-index: 55;
      animation-name: circleChange4;
  }
  .circleTwo, .circleThree, .circleFour  {
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
      width: 190px;
      height: 190px;
  }

  @keyframes circleChange{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange1{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1);opacity: 0.75;}
      50%{transform: scale(1);opacity: 0.5;}
      75%{transform: scale(1);opacity: 0.25;}
      100%{transform: scale(1);opacity: 0.75;}
  }
  @keyframes circleChange2{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange3{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }
  @keyframes circleChange4{
      0%{transform: scale(1);opacity: 1;}
      25%{transform: scale(1.2);opacity: 0.75;}
      50%{transform: scale(1.4);opacity: 0.5;}
      75%{transform: scale(1.6);opacity: 0.25;}
      100%{transform: scale(1.8);opacity: 0.05;}
  }

  .circleLeft{
      width: 250px;
      height: 259px;
      position: relative;
      left: 60px;
      border-left: 1px solid #FFB87F;
      border-radius: 50%;
      background: linear-gradient(90deg, rgb(255, 237, 227,1), rgb(255, 255, 255, 0.01),rgb(255, 255, 255, 0.01));
     }
  .circleRight{
      width: 250px;
      height: 259px;
      right: 125px;
      position: relative;
      border-right: 1px solid #FFB87F;
      border-radius: 50%;
      background: linear-gradient(90deg,rgba(255,255,255,0.01),rgba(255,255,255,0.01), rgba(255,237,227,1));
  }
  .circle-all{
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 400px;
      width: 600px;
  }
  .ballAll{
      height: 10px;
      width: 10px;
      background-color: #FF9456;
      border-radius: 50%;
      z-index: 6;
      color: #999;
  }
  .ballOne{
      top: 58px;
      position: absolute;
      left: 73px;
  }
  .ballTwo{
      top: 122px;
      position: absolute;
      left: 56px;
  }
  .ballThree{
      top: 195px;
      position: absolute;
      left: 75px;
  }
  .ballAndCircleLeft{
    position: relative;
    z-index: 9;
    width: 200px;
}
.ballAndCircleLeftActive{
    animation-name: ballAndCircleLeftAnimation;
    animation-duration: 3s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    animation-delay: 3s;
}
  .ballAndCircleRight{
      position: relative;
      z-index: 9;
      width: 200px;
  }
  .ballAndCircleRightActive{
      animation-name: ballAndCircleRightAnimation;
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
      animation-delay: 3s;
  }
  .ballFour{

    top: 14px;
    position: absolute;
    right: 128px;

  }
  .ballFive{
    top: 71px;
    position: absolute;
    right: 81px;
}

  .ballSix{
    top: 140px;
    position: absolute;
    right: 71px;
}

  .ballSeven{
    top: 222px;
    position: absolute;
    right: 111px;
  }


.ballEight{
    top: 31px;
    position: absolute;
    left: 30px;
}
.ballNine{

    top: 172px;
    position: absolute;
    left: 3px;

}
  @keyframes ballAndCircleLeftAnimation{
      0%{left: 20px;opacity: 0.05;}
      50%{left: 0px;opacity: 1;}
      100%{left: -20px;opacity: 0.05;}
  }
  @keyframes ballAndCircleRightAnimation{
      0%{right: 20px;opacity: 0.05;}
      50%{right: 0px;opacity: 1;}
      100%{right: -20px;opacity: 0.05;}
  }
  .outLeft{
      width: 250px;
      height: 259px;
      position: absolute;
      border-left: 1px solid #FFB87F;
      border-radius: 50%;
      z-index: 5;
      left: -5px;
      background: linear-gradient(90deg, rgb(255, 237, 227, 0.6), rgb(255, 255, 255, 0.01), rgb(255, 255, 255, 0.01));
  }
  .outLeftActive{
      animation-name: outLeftAnimation;
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
      animation-delay: 3s;
  }
  .outRight{
      width: 250px;
      height: 259px;
      z-index: 5;
      right: 14px;
      position: absolute;
      border-right: 1px solid #FFB87F;
      border-radius: 50%;
      background: linear-gradient(90deg,rgba(255,255,255,0.01),rgba(255,255,255,0.01), rgba(255,237,227,0.6) );

  }
  .outRightActive{
     animation-name: outRightAnimation;
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
      animation-delay: 3s;
  }
  @keyframes outLeftAnimation{
    0%{left: 30px;opacity: 0.05;}
    50%{left: -5px;opacity: 1;}
    100%{left: -30px;opacity: 0.05;}
  }
  @keyframes outRightAnimation{
    0%{right: 40px;opacity: 0.05;}
    50%{right: 20px;opacity: 1;}
    100%{right: -30px;opacity: 0.05;}
  }

  .check-inner{
    height: 100px;
    width: 100px;
    border-radius: 50%;
    border: 1px solid #FFC49A;
    color: #FF8040;
    font-size: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #fff !important;
  }
  .check-outer{
    height: 120px;
    width: 120px;
    border-radius: 50%;
    border: 1px dashed #E0E0E0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: -25px;
    margin-top: -10px;
  }
  .check-text-account{
    color:#999999;
    position: absolute;
    top: -52px;
  }
  .check-text-risk{
    color:#999999;
    position:absolute;
    left: 17px;
    top: -13px;
  }
  .check-text-analysis{
    color:#999999;
    position: absolute;
    top: 25px;
  }
  .ballOneText{
    width: 70px;
    margin-top: 10px;
    margin-left: -28px;

  }
  .ballTwoText{
    width: 130px;
    margin-top: 10px;
    margin-left: -52px;

  }
  .ballThreeText{
    width: 70px;
    margin-top: 10px;
    margin-left: -28px;

  }
  .ballFourText{
    width: 72px;
    margin-top: 10px;
    margin-left: -20px;

}
  .ballFiveText{
    width: 113px;
    margin-top: 10px;
    margin-left: -53px;

  }
  .ballSixText{
    width: 70px;
    margin-top: 10px;
    margin-left: -23px;

  }
  .ballSevenText{
    width: 120px;
    margin-top: 10px;
    margin-left: -38px;
  }
  .ballEightText{
    width: 70px;
    margin-top: 10px;
    margin-left: -23px;
  }
  .ballNineText{
    width: 110px;
    margin-top: 10px;
    margin-left: -23px;
  }
  .scanning-mask{
    display: flex;
    position: absolute;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    top: 1px;
    width: 100%;
    height: calc(100vh - 160px);
    background: rgba(255,255,255,0.9);
    margin-top: 30px;
  }
  .settleAccountsClassNameScan{
    width: 100px;
    height: 100px;
    border-radius: 50px;
    border: 0px;
  }
  .unSettleAccountsClassNameScan{
    width: 100px;
    height: 100px;
    border-radius: 50px;
    border: 0px;
  }
  .scanning{
    font-size: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
  }
</style>
</head>
<body>

 <div style="margin-left: 200px;">
  <div class="circle-all">
    <div class="ballAndCircleLeft ballAndCircleLeftActive" >
      <div class="outLeft outLeftActive">
        <div class="ballAll ballEight">
          <div class="ballEightText">扫描点一</div>
        </div>
        <div class="ballAll ballNine">
          <div class="ballNineText">扫描点二</div>
        </div>
      </div>
      <div class="ballAll ballOne">
        <div class="ballOneText">扫描点三</div>
      </div>
      <div class="ballAll ballTwo">
        <div class="ballTwoText">扫描点四</div>
      </div>
      <div class="ballAll ballThree">
        <div class="ballThreeText">扫描点五</div>
      </div>
      <div class="circleLeft"></div>
    </div>

    <div class="circleBox">
      <div class="circle">
          <div class="scanning">
            <div>扫描中...</div>
            <div>80%</div>
          </div>
      </div>
      <div class="circleOne"></div>
      <div class="circleTwo"></div>
      <div class="circleThree"></div>
      <div class="circleFour"></div>
    </div>
    <div class="ballAndCircleRight ballAndCircleRightActive">
      <div class="outRight outRightActive"></div>
      <div class="ballAll ballFour">
        <div class="ballFourText">扫描点六</div>
      </div>
      <div class="ballAll ballFive">
        <div class="ballFiveText">扫描点七扫描点</div>
      </div>
      <div class="ballAll ballSix">
        <div class="ballSixText">扫描点八</div>
      </div>
      <div class="ballAll ballSeven">
        <div class="ballSevenText">扫描点九</div>
      </div>
      <div class="circleRight"></div>
    </div>
  </div>
 </div>

</body>
</html>

希望本文对你有所帮助~~~

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值