美文网首页前端攻城狮程序员Java Web
用css3写一个守望先锋的loading动画

用css3写一个守望先锋的loading动画

作者: 忽如寄 | 来源:发表于2016-08-16 22:34 被阅读670次

    我是在前端网看到的效果,点击这里进入,自己看完源码后实现了一遍,以下介绍具体步骤:

    一、布局####

    观察效果,可以将其分为两个圆和里面的logo,所以简单分为三部分

    <div class="overwatch-container">
        <div class="out-ring-container">
        </div>
        <div class="inner-ring-container">
        </div>
        <div class="inner-img">
        </div>
    </div>
    

    二、实现外圆效果####

    观察外面的圆弧,肯定是用clip属性来实现了,显然要用4次,所以里面可以再分为两个部分,再用before和after两个伪元素,注意使用clip必须是用绝对定位元素,具体clip里面的值的话可以慢慢调了,如果你是一个游戏迷的话,不仿实现一个和游戏里一样的,几个月前,当我的朋友圈被这款游戏刷屏的时候,我也想玩玩的,可是当我打开官网的时候

    QQ截图20160816205229.png

    我竟无言以对,虽然我很支持正版,但是毕竟没钱。
    把外圆的相关样式丢进来,就可以实现效果了,这个关键也就在clip了

    <div class="overwatch-container">
        <div class="out-ring-container">
                    <div class="out-ring1"></div>
            <div class="out-ring2"></div>
        </div>
        <div class="inner-ring-container">
        </div>
        <div class="inner-img">
        </div>
    </div>
    
    * {
        margin: 0;
        padding: 0;
    }
    html {
        height: 100%;
        background: #282828;
    }
    .overwatch-container {
        width: 232px;
        margin: 50px auto;
        position: relative;
    }
    .out-ring1 {
        height: 220px;
        width: 220px;
        position: absolute;
        top: 6px;
        left: 6px;
    }
    .out-ring1::before, .out-ring1::after {
        content: "";
        height: 220px;
        width: 220px;
        border-radius: 50%;
        position: absolute;
        top: -6px;
        left: -6px;
        border: 6px solid rgba(161, 164, 176, 0.5);
    }
    .out-ring1::before {
        clip: rect(60px, 232px, 172px, 100px);
        transform: rotate(230deg);
    }
    .out-ring1::after {
        clip: rect(80px, 232px, 152px, 100px);
        transform: rotate(120deg);
    }
    .out-ring2 {
        position: absolute;
        top: 6px;
        left: 6px;
    }
    .out-ring2::before, .out-ring2::after {
        content: "";
        height: 220px;
        width: 220px;
        border-radius: 50%;
        position: absolute;
        top: -6px;
        left: -6px;
        border: 6px solid rgba(161, 164, 176, 0.5);
    }
    .out-ring2::before {
        clip: rect(105px, 232px, 127px, 100px);
    }
    .out-ring2::after {
        clip: rect(112px, 232px, 120px, 100px);
    }
    

    三、logo的实现####

    因为里面的圆的侧重于动画效果,故先写logo,观察logo,可以知道,这里看出这里必然要用到transform:rotate这个属性,logo中必然是一个大圆,其他部分可以通过方块实现,而最中间的部分可以用三角形来实现,css画三角形使用border就可以,具体的rotate需要具体调

    <div class="overwatch-container">
        <div class="out-ring-container">
                    <div class="out-ring1"></div>
            <div class="out-ring2"></div>
        </div>
        <div class="inner-ring-container">
        </div>
        <div class="inner-img">
                  <div class="inner-img-shelter"></div>
              <div class="inner-img-triangle"></div>
        </div>
    </div>
    
    * {
        margin: 0;
        padding: 0;
    }
    html {
        height: 100%;
        background: #282828;
    }
    .overwatch-container {
        width: 232px;
        margin: 50px auto;
        position: relative;
    }
    .out-ring1 {
        height: 220px;
        width: 220px;
        position: absolute;
        top: 6px;
        left: 6px;
    }
    .out-ring1::before, .out-ring1::after {
        content: "";
        height: 220px;
        width: 220px;
        border-radius: 50%;
        position: absolute;
        top: -6px;
        left: -6px;
        border: 6px solid rgba(161, 164, 176, 0.5);
    }
    .out-ring1::before {
        clip: rect(60px, 232px, 172px, 100px);
        transform: rotate(230deg);
    }
    .out-ring1::after {
        clip: rect(80px, 232px, 152px, 100px);
        transform: rotate(120deg);
    }
    .out-ring2 {
        position: absolute;
        top: 6px;
        left: 6px;
    }
    .out-ring2::before, .out-ring2::after {
        content: "";
        height: 220px;
        width: 220px;
        border-radius: 50%;
        position: absolute;
        top: -6px;
        left: -6px;
        border: 6px solid rgba(161, 164, 176, 0.5);
    }
    .out-ring2::before {
        clip: rect(105px, 232px, 127px, 100px);
    }
    .out-ring2::after {
        clip: rect(112px, 232px, 120px, 100px);
    }
    .inner-img {
        width: 120px;
        height: 120px;
        border: 20px solid #B6B8C0;
        background: transparent;
        border-radius: 50%;
        position: absolute;
        left: 0;
        top: 0;
        margin: 36px;
    }
    .inner-img::before {
        content: "";
        height: 20px;
        width: 66px;
        position: absolute;
        background: #B6B8C0;
        bottom: 0;
        left: 0;
        transform: rotate(-45deg);
        transform-origin: left;
    }
    .inner-img::after {
        content: "";
        height: 20px;
        width: 66px;
        position: absolute;
        background: #B6B8C0;
        bottom: 0;
        right: 0;
        transform: rotate(45deg);
        transform-origin: right;
    }
    .inner-img-shelter::before, .inner-img-shelter::after {
        content: "";
        height: 4px;
        width: 21px;
        background: #282828;
        position: absolute;
        top: 15px;
    }
    .inner-img-shelter::before {
        left: -4px;
        transform: rotate(45deg);
        transform-origin: bottom right;
    }
    .inner-img-shelter::after {
        right: -4px;
        transform: rotate(-45deg);
        transform-origin: bottom left;
    }
    .inner-img-triangle::before {
        content: "";
        width: 0px;
        height: 0px;
        border-width: 0px 0px 50px 20px;
        border-left-color: transparent;
        border-bottom-color: #B6B8C0;
        border-style: solid;
        position: absolute;
        top: 20px;
        left: 34px;
    }
    .inner-img-triangle::after {
        content: "";
        width: 0px;
        height: 0px;
        border-width: 0px 20px 50px 00px;
        border-right-color: transparent;
        border-bottom-color: #B6B8C0;
        border-style: solid;
        position: absolute;
        top: 20px;
        right: 34px;
    }
    

    三、实现里圆效果####

    里圆的效果侧重于动画了,里面的效果都是通过不断调整实现的,我也是看的源代码,里面的效果归根到底还是基本的圆形loading加载动画,一般圆形的进度条我们可以使用上面提到的clip实现

    23333
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title> loading</title>
    <meta name="description" content="">
    <meta name="keywords" content="">
    <link href="" rel="stylesheet">
    <style>
        *{
            margin:0;
            padding:0;
        }
        body{
            width:220px;
            margin:20px auto;
        }
        .loading-container{
            position:relative;
        }
        .loading{
            width:200px;
            height:200px;
            border-radius: 50%;
            border:10px solid yellow;
            animation: loading 2s linear infinite;
            position:absolute;
        }
        .loading2{
            width:200px;
            height:200px;
            border-radius:50%;
            border:10px solid yellow;
            position:absolute;
            transform: rotate(180deg);
            clip:rect(0px,0px,0px,0px);
            animation:loading2 2s  linear infinite;
        }
        @keyframes loading{
            0%{
                clip:rect(0px, 220px,0px,110px);
            }
            50%{
                clip:rect(0px,220px,220px,110px);
            }
            100%{
                clip:rect(0px,220px,220px,110px);
            }
        }
        @keyframes loading2{
            0%{
                clip:rect(0px, 220px,0px,110px);
            }
            50%{
                clip:rect(0px, 220px,0px,110px);
            }
            100%{
                clip:rect(0px, 220px,220px,110px);
            }
        }
    </style>
    </head>
    <body>
        <div class="loading-container">
            <div class="loading"></div>
            <div class="loading2"></div>
        </div>
    </body>
    </html>
    

    如果通过js添加一些数字就更加形象了

    2334.gif

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title> loading</title>
    <meta name="description" content="">
    <meta name="keywords" content="">
    <link href="" rel="stylesheet">
    <style>
    *{
    margin:0;
    padding:0;
    }
    body{
    width:220px;
    margin:20px auto;
    }
    .loading-container{
    position:relative;
    }
    .loading{
    width:200px;
    height:200px;
    border-radius: 50%;
    border:10px solid yellow;
    animation: loading 2s linear infinite;
    position:absolute;
    }
    .loading2{
    width:200px;
    height:200px;
    border-radius:50%;
    border:10px solid yellow;
    position:absolute;
    transform: rotate(180deg);
    clip:rect(0px,0px,0px,0px);
    animation:loading2 2s linear infinite;
    }
    @keyframes loading{
    0%{
    clip:rect(0px, 220px,0px,110px);
    }
    50%{
    clip:rect(0px,220px,220px,110px);
    }
    100%{
    clip:rect(0px,220px,220px,110px);
    }
    }
    @keyframes loading2{
    0%{
    clip:rect(0px, 220px,0px,110px);
    }
    50%{
    clip:rect(0px, 220px,0px,110px);
    }
    100%{
    clip:rect(0px, 220px,220px,110px);
    }
    }
    </style>
    </head>
    <body>
    <div class="loading-container">
    <div class="loading"></div>
    <div class="loading2"></div>
    </div>
    <script>
    var number=document.getElementById("number");
    function changeNumber(){
    var text=number.innerText;
    var newText=Number(text.replace(/%/, ''));
    if(newText<100){
    newText++;
    }
    else{
    clearTimeout(timer);
    }
    number.innerText=newText+"%";
    var timer=setTimeout(changeNumber,20);
    }
    changeNumber();
    </script>
    </body>
    </html>

    使用clip的一个特点是过程中会出现棱角,这个可能不是我们想要的,我们可以使用border来代替,从而消除棱角
    

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title> loading2</title>
    <meta name="description" content="">
    <meta name="keywords" content="">
    <link href="" rel="stylesheet">
    <style>
    *{
    margin:0;
    padding:0;
    }
    body{
    width:220px;
    margin:20px auto;
    }
    .loading-container{
    position:relative;
    }
    .loading{
    width:110px;
    height:220px;
    position:absolute;
    overflow: hidden;
    }
    .loading-content{
    width:200px;
    height:200px;
    border:10px solid yellow;
    border-radius: 50%;
    border-bottom-color:transparent;
    border-right-color:transparent;
    transform:rotate(-225deg);
    animation: loading 2s infinite linear;
    }
    .loading2{
    width:110px;
    height:220px;
    position:absolute;
    overflow: hidden;
    right:0;
    top:0;
    transform:rotate(180deg);
    }
    .loading2-content{
    width:200px;
    height:200px;
    border:10px solid yellow;
    border-radius: 50%;
    border-bottom-color:transparent;
    border-right-color:transparent;
    transform:rotate(-225deg);
    animation: loading2 2s infinite linear;
    }
    .number{
    width:220px;
    height:40px;
    position:absolute;
    top:90px;
    text-align: center;
    font-size: 30px;
    font-weight:bold;
    }
    @keyframes loading{
    0%{
    transform: rotate(-225deg);
    }
    50%{
    transform: rotate(-225deg);
    }
    100%{
    transform: rotate(-45deg);
    }
    }
    @keyframes loading2{
    0%{
    transform: rotate(-225deg);
    }
    50%{
    transform: rotate(-45deg);
    }
    100%{
    transform: rotate(-45deg);
    }
    }
    </style>
    </head>
    <body>
    <div class="loading-container">
    <div class="loading">
    <div class="loading-content"></div>
    </div>
    <div class="loading2">
    <div class="loading2-content"></div>
    </div>
    <div class="number" id="number">0%</div>
    </div>
    <script>
    var number=document.getElementById("number");
    function changeNumber(){
    var text=number.innerText;
    var newText=Number(text.replace(/%/, ''));
    if(newText<100){
    newText++;
    }
    else{
    clearTimeout(timer);
    }
    number.innerText=newText+"%";
    var timer=setTimeout(changeNumber,20);
    }
    changeNumber();
    </script>
    </body>
    </html>

    而守望先锋的效果也正是这个的延伸的微调,具体可以看源码
    ####四、添加动画效果####
    这里的动画效果没有什么技巧,只是不断的rotate微调而已,具体情况可以参照源码
    

    <div class="overwatch-container">
    <div class="out-ring-container">
    <div class="out-ring1"></div>
    <div class="out-ring2"></div>
    </div>
    <div class="inner-ring-container">
    <div class="inner-ring1"></div>
    <div class="inner-ring2">
    <div class="inner-ring2-container">
    <div class="inner-ring2-content"></div>
    </div>
    </div>
    <div class="inner-ring3">
    <div class="inner-ring3-container1">
    <div class="inner-ring3-container1-content">
    <div class="inner-ring3-content1"></div>
    </div>
    </div>
    <div class="inner-ring3-container2">
    <div class="inner-ring3-container2-content">
    <div class="inner-ring3-content2"></div>
    </div>
    </div>
    </div>
    </div>
    <div class="inner-img">
    <div class="inner-img-shelter"></div>
    <div class="inner-img-triangle"></div>
    </div>
    </div>

    • {
      margin: 0;
      padding: 0;
      }
      html {
      height: 100%;
      background: #282828;
      }
      .overwatch-container {
      width: 232px;
      margin: 50px auto;
      position: relative;
      }
      .out-ring1 {
      height: 220px;
      width: 220px;
      position: absolute;
      top: 6px;
      left: 6px;
      }
      .out-ring1::before, .out-ring1::after {
      content: "";
      height: 220px;
      width: 220px;
      border-radius: 50%;
      position: absolute;
      top: -6px;
      left: -6px;
      border: 6px solid rgba(161, 164, 176, 0.5);
      }
      .out-ring1::before {
      clip: rect(60px, 232px, 172px, 100px);
      transform: rotate(230deg);
      animation: out-ring1-before 3s cubic-bezier(0.34, 0.07, 0.68, 0.93) infinite
      }
      .out-ring1::after {
      clip: rect(80px, 232px, 152px, 100px);
      transform: rotate(120deg);
      animation: out-ring1-after 3s linear infinite
      }
      @keyframes out-ring1-before {
      from {
      transform: rotate(0deg);
      }
      to {
      transform: rotate(360deg);
      }
      }
      @keyframes out-ring1-after {
      from {
      transform: rotate(120deg);
      }
      to {
      transform: rotate(480deg);
      }
      }
      .out-ring2 {
      position: absolute;
      top: 6px;
      left: 6px;
      }
      .out-ring2::before, .out-ring2::after {
      content: "";
      height: 220px;
      width: 220px;
      border-radius: 50%;
      position: absolute;
      top: -6px;
      left: -6px;
      border: 6px solid rgba(161, 164, 176, 0.5);
      }
      .out-ring2::before {
      clip: rect(105px, 232px, 127px, 100px);
      animation: out-ring2-before 3s cubic-bezier(0.34, 0.07, 0.68, 0.93) infinite;
      }
      .out-ring2::after {
      clip: rect(112px, 232px, 120px, 100px);
      animation: out-ring2-before 3s linear infinite reverse;
      }
      @keyframes out-ring2-before {
      from {
      transform: rotate(270deg);
      }
      to {
      transform: rotate(-90deg);
      }
      }
      @keyframes out-ring2-after {
      from {
      transform: rotate(120deg);
      }
      to {
      transform: rotate(480deg);
      }
      }
      .inner-img {
      width: 120px;
      height: 120px;
      border: 20px solid #B6B8C0;
      background: transparent;
      border-radius: 50%;
      position: absolute;
      left: 0;
      top: 0;
      margin: 36px;
      }
      .inner-img::before {
      content: "";
      height: 20px;
      width: 66px;
      position: absolute;
      background: #B6B8C0;
      bottom: 0;
      left: 0;
      transform: rotate(-45deg);
      transform-origin: left;
      }
      .inner-img::after {
      content: "";
      height: 20px;
      width: 66px;
      position: absolute;
      background: #B6B8C0;
      bottom: 0;
      right: 0;
      transform: rotate(45deg);
      transform-origin: right;
      }
      .inner-img-shelter::before, .inner-img-shelter::after {
      content: "";
      height: 4px;
      width: 21px;
      background: #282828;
      position: absolute;
      top: 15px;
      }
      .inner-img-shelter::before {
      left: -4px;
      transform: rotate(45deg);
      transform-origin: bottom right;
      }
      .inner-img-shelter::after {
      right: -4px;
      transform: rotate(-45deg);
      transform-origin: bottom left;
      }
      .inner-img-triangle::before {
      content: "";
      width: 0px;
      height: 0px;
      border-width: 0px 0px 50px 20px;
      border-left-color: transparent;
      border-bottom-color: #B6B8C0;
      border-style: solid;
      position: absolute;
      top: 20px;
      left: 34px;
      }
      .inner-img-triangle::after {
      content: "";
      width: 0px;
      height: 0px;
      border-width: 0px 20px 50px 00px;
      border-right-color: transparent;
      border-bottom-color: #B6B8C0;
      border-style: solid;
      position: absolute;
      top: 20px;
      right: 34px;
      }
      .inner-ring-container {
      width: 200px;
      height: 200px;
      position: absolute;
      top: 16px;
      left: 16px;
      background: transform;
      }
      .inner-ring1 {
      width: 180px;
      height: 180px;
      border: 10px solid #F9D64A;
      border-radius: 50%;
      position: absolute;
      clip: rect(90px, 200px, 110px, 110px);
      animation: inner-ring1 3s infinite linear;
      z-index: 2;
      }
      @keyframes inner-ring1 {
      from {
      transform: rotate(0deg);
      }
      to {
      transform: rotate(-360deg);
      }
      }
      .inner-ring3 {
      width: 200px;
      height: 200px;
      background: transparent;
      position: absolute;
      top: 0;
      left: 0;
      animation: inner-ring3 infinite 2s linear;
      }
      .inner-ring3-container1 {
      width: 100px;
      height: 200px;
      overflow: hidden;
      position: absolute;
      top: 0;
      left: 0;
      }
      .inner-ring3-container1-content {
      width: 200px;
      height: 200px;
      position: absolute;
      animation: inner-ring3-container1-content 2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
      }
      .inner-ring3-content1 {
      height: 180px;
      width: 180px;
      border-radius: 50%;
      border: 10px solid #4D4C2D;
      border-bottom-color: transparent;
      border-right-color: transparent;
      transform: rotate(-45deg);
      animation: inner-ring3-content1 2s linear infinite;
      }
      @keyframes inner-ring3 {
      from {
      transform: rotate(0deg);
      }
      to {
      transform: rotate(360deg);
      }
      }
      @keyframes inner-ring3-content1 {
      from {
      transform: rotate(-45deg);
      }
      35.5% {
      transform: rotate(-45deg);
      }
      50% {
      transform: rotate(135deg);
      }
      to {
      transform: rotate(135deg);
      }
      }
      @keyframes inner-ring3-container1-content {
      0% {
      transform: rotate(0deg);
      }
      64.5% {
      transform: rotate(0deg);
      }
      100% {
      transform: rotate(180deg);
      }
      }
      .inner-ring3-container2 {
      width: 100px;
      height: 200px;
      overflow: hidden;
      position: absolute;
      top: 0;
      right: 0;
      }
      .inner-ring3-container2-content {
      width: 200px;
      height: 200px;
      position: absolute;
      top: 0;
      left: -100px;
      animation: inner-ring3-container2-content linear 2s infinite;
      }
      .inner-ring3-content2 {
      height: 180px;
      width: 180px;
      border-radius: 50%;
      border: 10px solid #4D4C2D;
      border-bottom-color: transparent;
      border-left-color: transparent;
      transform: rotate(45deg);
      animation: inner-ring3-content2 2s cubic-bezier(0.5, 0, 1, 0.5) infinite;
      }
      @keyframes inner-ring3-content2 {
      from {
      transform: rotate(45deg);
      }
      35.5% {
      transform: rotate(225deg);
      }
      to {
      transform: rotate(225deg);
      }
      }
      @keyframes inner-ring3-container2-content {
      0% {
      transform: rotate(0deg);
      }
      50% {
      transform: rotate(0deg);
      }
      64.5% {
      transform: rotate(180deg);
      }
      100% {
      transform: rotate(180deg);
      }
      }
      .inner-ring2 {
      width: 200px;
      height: 200px;
      z-index: 2;
      position: absolute;
      animation: inner-ring2 infinite 2s linear;
      }
      .inner-ring2-container {
      width: 100px;
      height: 200px;
      overflow: hidden;
      position: absolute;
      top: 0;
      left: 0;
      }
      .inner-ring2-content {
      height: 180px;
      width: 180px;
      border-radius: 50%;
      border: 10px solid #F9D64A;
      border-bottom-color: transparent;
      border-right-color: transparent;
      z-index: 2;
      animation: inner-ring2-content infinite linear 2s;
      }
      @keyframes inner-ring2 {
      0% {
      transform: rotate(0deg);
      }
      50% {
      transform: rotate(90deg);
      }
      100% {
      transform: rotate(360deg);
      }
      }
      @keyframes inner-ring2-content {
      0% {
      transform: rotate(-205deg);
      }
      50% {
      transform: rotate(-135deg);
      }
      100% {
      transform: rotate(-205deg);
      }
      }
    
    
    

    相关文章

      网友评论

        本文标题:用css3写一个守望先锋的loading动画

        本文链接:https://www.haomeiwen.com/subject/iagpsttx.html