CSS动画:数字增量效果

时间:2015-01-15 04:15:24

标签: css css3 animation css-animations

我希望在数字快速变化时获得动画效果,例如:http://jsbin.com/kevalutupe/1/

我想单独使用这个CSS(我知道如何在JS中编写代码),我不想使用JS,因为我觉得锤击DOM并不是最好的解决方案。 CSS完全可以吗?

我并没有对实际正确递增的数字感到困惑,我只是在效果之后。

1 个答案:

答案 0 :(得分:28)

使用CSS3动画绝对可以实现数字旋转效果,你还可以使用一小部分JS设置终点并实际获得整个功能。

方法说明:

  1. 创建div,通过将其高度和宽度设置为1em,它始终只显示一个数字。 div的溢出设置为隐藏,以便只显示一行。
  2. 在此div范围内,span包含从1到0的所有数字,并且相对于父项定位。
  3. span的初始位置为0px或0em,但在animation期间,顶部位置发生变化,以致span给人以向上移动的印象。因为div一次只能显示一个数字,所以它会产生旋转效果(或其他数字的效果消失)。
  4. 通过为每个span元素设置固定的顶部位置来实现最终位置。 0em表示第1行可见(编号1),-2em表示第3行可见(编号3),依此类推。
  5. 增加或减少动画持续时间会使旋转效果快速或缓慢地发生。动画迭代计数设置为5,以产生旋转器多次旋转的错觉。
  6. 注意:使用这种方法,旋转看起来像每次都是整个圆圈而不是像问题的JSBin样本那样第一个数字的3到4只是一个步骤而不是一个完整的圆圈。

    div {
      width: 1em;
      height: 1em;
      overflow: hidden;
      line-height: 1em;
      display: inline-block;
    }
    span {
      position: relative;
    }
    .animate {
      -webkit-animation: spinit 0.2s 5;
      -moz-animation: spinit 0.2s 5;
      animation: spinit 0.2s 5;
    }
    @-webkit-keyframes spinit {
      0% {
        top: 0em;
      }
      50% {
        top: -5em;
      }
      100% {
        top: -9em;
      }
    }
    @-moz-keyframes spinit {
      0% {
        top: 0em;
      }
      50% {
        top: -5em;
      }
      100% {
        top: -9em;
      }
    }
    @keyframes spinit {
      0% {
        top: 0em;
      }
      50% {
        top: -5em;
      }
      100% {
        top: -9em;
      }
    }
    
    /* Setting the required value to top will make the spinner end at that number */
    
    #digit1 {
      top: -4em;
      /* -4em means 5 will be the number */
    }
    #digit2 {
      top: -2em;
    }
    #digit3 {
      top: 0em;
    }
    <div>
      <span class="animate" id='digit1'>1 2 3 4 5 6 7 8 9 0</span>
    </div>
    <div>
      <span class="animate" id='digit2'>1 2 3 4 5 6 7 8 9 0</span>
    </div>
    <div>
      <span class="animate" id='digit3'>1 2 3 4 5 6 7 8 9 0</span>
    </div>


    以下是使用JavaScript的示例,其中动画效果通过CSS实现,但动画的触发和端点的设置是使用JavaScript实现的。

    JS代码几乎是自我解释的。我们所做的只是以下几点:

    1. 为按钮的click事件创建一个侦听器,在其中我们将animate类添加到属于此动画效果的所有span元素中。这是因为我们希望动画仅在单击按钮时发生。
    2. 当动画结束(或旋转完成)时,我们将每个top的{​​{1}}属性设置为一个随机数。这意味着每个跨度将显示不同的数字。
    3. 在动画结束时,我们还调用另一个函数来删除span类,这样当我们再次单击该按钮时,动画可以重新开始。
    4. animate
      window.onload = function() {
        var spinner = document.getElementById('spinner');
        spinner.onclick = spinit;
      
        var el = document.querySelectorAll("span[id*=digit]");
        for (i = 0; i < el.length; i++) {
          el[i].addEventListener("animationend", randomize, false);
          el[i].addEventListener("webkitAnimationEnd", randomize, false);
          el[i].addEventListener("oanimationend", randomize, false);
          el[i].addEventListener("MSAnimationEnd", randomize, false);
        }
      }
      
      function randomize() {
        var rand = Math.floor(Math.random() * 9);
        this.style.top = -1 * rand + "em";
        this.classList.toggle('animate');
      }
      
      function spinit() {
        var el = document.querySelectorAll("span[id*=digit]");
        for (i = 0; i < el.length; i++) {
          el[i].classList.toggle('animate');
        }
      }
      div {
        width: 1em;
        height: 1em;
        overflow: hidden;
        line-height: 1em;
        display: inline-block;
      }
      span {
        position: relative;
      }
      .animate {
        -webkit-animation: spinit 0.2s 5;
        -moz-animation: spinit 0.2s 5;
        animation: spinit 0.2s 5;
      }
      @-webkit-keyframes spinit {
        0% {
          top: 0em;
        }
        50% {
          top: -5em;
        }
        100% {
          top: -9em;
        }
      }
      @-moz-keyframes spinit {
        0% {
          top: 0em;
        }
        50% {
          top: -5em;
        }
        100% {
          top: -9em;
        }
      }
      @keyframes spinit {
        0% {
          top: 0em;
        }
        50% {
          top: -5em;
        }
        100% {
          top: -9em;
        }
      }
      
      /* Set the value according to the on-load position of the spinner */
      
      #digit1 {
        top: -4em;
        /* -4em means 5 will be the number */
      }
      #digit2 {
        top: -2em;
      }
      #digit3 {
        top: 0em;
      }


      版本2:(仅使用数字增量效果而非旋转效果)

      这是使用与前一个代码大致相同的代码创建的,但与前一个代码不同,<div> <span id='digit1'>1 2 3 4 5 6 7 8 9 0</span> </div> <div> <span id='digit2'>1 2 3 4 5 6 7 8 9 0</span> </div> <div> <span id='digit3'>1 2 3 4 5 6 7 8 9 0</span> </div> <button id='spinner'>Spin It</button>使一个数字从一个数字移动到另一个数字(从而产生旋转效果),这里是动画使运动更像是从一个数字突然跳到另一个数字,从而产生增量效果。

      通过将animation位置保持不变直到其移动到下一个位置(即top设置为top直到9.9%来实现跳转动画但是在10%时突然变为0em)。

      -1em
      window.onload = function() {
        var spinner = document.getElementById('spinner');
        spinner.onclick = spinit;
      
        var el = document.querySelectorAll("span[id*=digit]");
        for (i = 0; i < el.length; i++) {
          el[i].addEventListener("animationend", randomize, false);
          el[i].addEventListener("webkitAnimationEnd", randomize, false);
          el[i].addEventListener("oanimationend", randomize, false);
          el[i].addEventListener("MSAnimationEnd", randomize, false);
        }
      }
      
      function randomize() {
        var rand = Math.floor(Math.random() * 9);
        this.style.top = -1 * rand + "em";
        this.classList.toggle('animate');
      }
      
      function spinit() {
        var el = document.querySelectorAll("span[id*=digit]");
        for (i = 0; i < el.length; i++) {
          el[i].classList.toggle('animate');
        }
      }
      div {
        width: 1em;
        height: 1em;
        overflow: hidden;
        line-height: 1em;
        display: inline-block;
      }
      span {
        position: relative;
      }
      .animate {
        -webkit-animation: spinit 0.2s 5;
        -moz-animation: spinit 0.2s 5;
        animation: spinit 0.2s 5;
      }
      @-webkit-keyframes spinit {
        0% { top: 0em; }
        9.9% { top: 0em; }
        10%{ top: -1em; }
        19.9%{ top: -1em; }
        20%{ top: -2em; }
        29.9%{ top: -2em; }
        30%{ top: -3em; }
        39.9%{ top: -3em; }
        40%{ top: -4em; }
        49.9%{ top: -4em; }
        50% { top: -5em; }
        59.9%{ top: -5em; }
        60%{ top: -6em; }
        69.9%{ top: -6em; }
        70%{ top: -7em; }
        79.9%{ top: -7em; }
        80%{ top: -8em; }
        89.9%{ top: -8em; }
        90%{ top: -9em; }
        99.9%{ top: -9em; }
        100% { top: -9em; }
      }
      @-moz-keyframes spinit {
        0% { top: 0em; }
        9.9% { top: 0em; }
        10%{ top: -1em; }
        19.9%{ top: -1em; }
        20%{ top: -2em; }
        29.9%{ top: -2em; }
        30%{ top: -3em; }
        39.9%{ top: -3em; }
        40%{ top: -4em; }
        49.9%{ top: -4em; }
        50% { top: -5em; }
        59.9%{ top: -5em; }
        60%{ top: -6em; }
        69.9%{ top: -6em; }
        70%{ top: -7em; }
        79.9%{ top: -7em; }
        80%{ top: -8em; }
        89.9%{ top: -8em; }
        90%{ top: -9em; }
        99.9%{ top: -9em; }
        100% { top: -9em; }
      }
      @keyframes spinit {
        0% { top: 0em; }
        9.9% { top: 0em; }
        10%{ top: -1em; }
        19.9%{ top: -1em; }
        20%{ top: -2em; }
        29.9%{ top: -2em; }
        30%{ top: -3em; }
        39.9%{ top: -3em; }
        40%{ top: -4em; }
        49.9%{ top: -4em; }
        50% { top: -5em; }
        59.9%{ top: -5em; }
        60%{ top: -6em; }
        69.9%{ top: -6em; }
        70%{ top: -7em; }
        79.9%{ top: -7em; }
        80%{ top: -8em; }
        89.9%{ top: -8em; }
        90%{ top: -9em; }
        99.9%{ top: -9em; }
        100% { top: -9em; }
      }
      
      /* Set the value according to the on-load position of the spinner */
      
      #digit1 {
        top: -4em;
        /* -4em means 5 will be the number */
      }
      #digit2 {
        top: -2em;
      }
      #digit3 {
        top: 0em;
      }