前端纯css实现一个仪表盘底座动画

4,056 阅读2分钟

前端的烦恼

昨天看到jym有个沸点 觉得有点意思做前端的也经常碰到

问题点:产品同事需要有动效,UI同事却只能给到静态切图

image.png

解决思路:

方法1:跟产品同事反馈,UI不能给到Gif动图,此需求做不了 [矛盾转移到产品和UI😁]

方法2:找UI提供底座分离好的svg切图,代码做动画也能改配色 [与其我累不如苦UI😁]

方案3:纯css实现仪表盘底座,无非就是几个圆环控制好z-index 和 transform: rotateX(37deg) rotateY(25deg) rotateZ(15deg); [就是苦了自己😁]

在线查看demo

纯css实现具体代码():

写的好玩,代码粗糙,大佬们见笑了,抛砖引玉

1.gif

前端部分

    <!-- 仪表盘组件 start -->
    <div class="ui-dash-box">
      <!-- value start -->
      <h1>78</h1>
      <h3>100</h3>
      <!-- value end -->
      <!-- bg start -->
      <div class="ui-dash-bg">
        <i/><i/><i/><i/><i/>
      </div>
      <!-- bg end -->
    </div> 
    <!-- 仪表盘组件 end --> 

css样式部分

// 仪表盘组件css集 ----------------
.ui-dash-box{
  $boxSize:180px; //仪表盘宽高大小
  $boxBg:#090f1f; //仪表盘背景色

  position: relative;
  display: flex; 
  align-items: center;
  justify-content: center;
  width: $boxSize;
  height: $boxSize; 
  h1,h3{ 
    font-weight: normal;
    z-index: 100;
    margin-bottom: 60px;
  }
  // 仪表盘值css
  h1{
    font-size: 36px; 
    color:#fff;
    margin-left: 60px;
  }
  h3{
    font-size: 14px; 
    color:#b9b9b9;
    padding-top: 14px;
    &::before{
      content:'/';
      font-size:14px;
      padding:0px 3px 0px 5px;
    }
  }
  // 仪表盘底座css
  .ui-dash-bg{
    position: absolute;
    width: $boxSize;
    height: $boxSize;
    background: $boxBg;
    transform: rotateX(37deg) rotateY(25deg) rotateZ(15deg);
    // 动画-顺时针旋转 
    @keyframes animationRotateZ {
      from{
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
    // 动画-逆时针旋转 
    @keyframes animationRotateF {
      from{
        transform: rotate(0deg);
      }
      to {
        transform: rotate(-360deg);
      }
    }
    // 动画-3D上下移动 
    @keyframes animationMove {
      0% {
        top:20px;
      }
      50% {
        top:-30px;
      }
      100% {
        top:20px;
      }
    }
    // 动画-透明度变化 
    @keyframes animationOpacity {
      0% {
        opacity: 1;
      }
      50% {
        opacity: 0.6;
      }
      100% {
        opacity: 1;
      }
    }
    // 动画-透明度&圆半径变化 
    @keyframes animationSize {
      0% {
        opacity: 1;
        width: 90px;
        height: 90px;
      }
      50% {
        opacity: 0.6;
        width: 60px;
        height: 60px;
      }
      100% {
        opacity: 1;
        width: 90px;
        height: 90px;
      }
    }

    i{
      display: block;
      position: absolute;
      border-radius: 100%;
      top:0;
      left:0;
      right:0;
      bottom:0;
      margin: auto;

      &:nth-child(1){
        width: $boxSize - 40;
        height: $boxSize - 40;
        background: conic-gradient(#f1b434 0%,transparent 120%);
        mask: radial-gradient(circle at center, transparent 0px 56%,#000 58% 90%,transparent 91% 100%);
        top:-40px;
        z-index:80;
        animation: animationRotateZ 3s linear infinite;
      }

      &:nth-child(2){
        width: $boxSize - 10;
        height: $boxSize - 10;
        border:1px dashed rgba(241, 180, 52,0.6); 
        // box-shadow: inset 1px 1px 5px rgba(241, 180, 52,0.3); 
        top:10px;  
        right: 10px;
        z-index:60;
      }

      &:nth-child(3){
        width: $boxSize - 80;
        height: $boxSize - 80;
        background-image: radial-gradient(rgba(241, 180, 52,0.7), transparent);
        filter:blur(9px);
        top:-40px;
        right:-10px;
        z-index:70;
        box-shadow: -6px 15px 30px rgba(241, 180, 52,0.4); 
        animation: animationOpacity 2s linear infinite;
      }
      
      &:nth-child(4){
        width: $boxSize - 50;
        height: $boxSize - 50;
        border:2px solid rgba(241, 180, 52,0.4); 
        top:20px; 
        right: 10px;
        box-shadow: -6px 15px 30px rgba(241, 180, 52,0.2); 
        z-index:60;
        animation: animationMove 3s linear infinite;
      }
      
      &:nth-child(5){
        width: 90px;
        height: 90px;
        border:1px solid rgba(241, 180, 52,0.6); 
        top: -50px;
        right: 0px;
        z-index: 10;
        animation: animationSize 2s linear infinite;
      }

    }
  }
}