秀动票夹二维码边框动画效果实现

491 阅读2分钟

今天第一次使用秀动买livehouse的门票,看到票夹二维码边框的动画效果还不错,于是也动手实现一下。

代码
效果图(gif录制出来看起来有点卡顿,实际运行丝滑)

exp.gif

实现步骤拆解
  • 第一步实现渐变背景

    实现渐变背景主要是使用linear-gradient() 函数,代码如下:

    <div class="border"></div>
    
    .border {
      position: relative;
      width: 200px;
      height: 200px;
    }
    .border:before {
      position: absolute;
      content: "";
      width: 100%;
      height: 100%;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: linear-gradient(blueviolet, lightpink);
    }
    

    效果如下:

exp1.png

  • 第二步实现渐变边框

    实现渐变边框其实是个障眼法,给 .border 元素设置背景色白色,设置padding: 4px,然后通过background-clip 属性将背景裁剪到内容框,这样就模拟了一个4px的边框。

    代码如下:

    .border {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 40px;
      padding: 4px;
      background: #fff;
      background-clip: content-box;
    }
    .border:before {
      position: absolute;
      content: "";
      width: 100%;
      height: 100%;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: -1;
      background: linear-gradient(blueviolet, lightpink);
    }
    

    效果如下:

exp2.png

  • 第三步实现动画效果

    最后一步使用rotate()animation 结合让边框旋转起来,注意这里 .border:before 的宽高不是100%,而是150%,.border 元素的 overflow 设置为hidden。同时linear-gradient() 再增加 20% 的白色渐变,实现白色的缺口。

    最终代码如下:

    .border {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 40px;
      padding: 4px;
      background: #fff;
      background-clip: content-box;
      overflow: hidden;
    }
    .border:before {
      position: absolute;
      content: "";
      width: 150%;
      height: 150%;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%) rotate(0deg);
      z-index: -1;
      background: linear-gradient(#fff 0, #fff 20%, blueviolet, lightpink);
      animation: rotate 2s linear -1s infinite;
    }
    @keyframes rotate {
      0% {
        transform: translate(-50%, -50%) rotate(0deg);
      }
      25% {
        transform: translate(-50%, -50%) rotate(90deg);
      }
      50% {
        transform: translate(-50%, -50%) rotate(180deg);
      }
      75% {
        transform: translate(-50%, -50%) rotate(270deg);
      }
      100% {
        transform: translate(-50%, -50%) rotate(360deg);
      }
    }
    

欢迎各位看官批评与指正