CSS动画:数字递增效果

Posted

技术标签:

【中文标题】CSS动画:数字递增效果【英文标题】:CSS Animation: Number increment effect 【发布时间】:2015-03-13 10:48:15 【问题描述】:

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

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

我对实际正确递增的数字并不在意,我只是在追求效果。

【问题讨论】:

【参考方案1】:

使用 CSS3 动画绝对可以实现数字旋转效果,更好的是,您还可以使用少量 JS 设置端点并实际获得全部功能。

方法说明:

    创建了div,通过将其高度和宽度设置为1em,它始终只显示一个数字。 div 的溢出设置为隐藏,以便仅显示一行。 在这个 div 中创建了一个包含从 1 到 0 的所有数字的 span,并相对于父级进行定位。 span 的初始位置为 0px 或 0em,但在 animation 期间顶部位置发生变化,因此 span 给人以向上移动的印象。因为div 一次只能显示一个数字,所以会产生旋转效果(或其他数字消失的效果)。 最终位置是通过为每个span 元素设置一个固定的顶部位置来实现的。 0em 表示第一行可见(数字 1),-2em 表示第三行可见(数字 3),依此类推。 增加或减少动画持续时间将使旋转效果快速或缓慢发生。动画迭代计数设置为 5,以产生微调器旋转多次的错觉。

注意: 使用这种方法,旋转看起来每次都会转一圈,而不像有问题的 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 代码几乎是不言自明的。我们正在做的事情如下:

    为按钮的单击事件创建一个侦听器,并在其中将animate 类添加到作为此动画效果一部分的所有span 元素。这是因为我们希望动画仅在单击按钮时发生。 当动画结束(或旋转完成)时,我们将每个spantop 属性设置为某个随机数。这意味着每个跨度将显示不同的数字。 在动画结束时,我们还调用另一个函数来删除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;
<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>

第 2 版:(仅具有数字增量效果而不是旋转效果)

这是使用与前一个基本相同的代码创建的,但与前一个不同的是,animation 使从一个数字到另一个数字的移动是渐进的(从而产生旋转效果),这里的动画使运动更像是从一个数字突然跳到另一个数字,从而产生增量效应。

跳跃是通过保持top 的位置不变直到它即将移动到下一个来实现的(也就是说,top 设置为0em 直到动画的 9.9%,但在 10 % 突然变成-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;
<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>

【讨论】:

玩过这个,有没有什么办法可以让旋转效果消失?我想要的只是数字在静态位置快速变化的效果。 @duck:我为答案伙伴添加了另一个变体。这看起来更接近您想要实现的目标。就我个人而言,我不认为使用 CSS 可以实现更多。

以上是关于CSS动画:数字递增效果的主要内容,如果未能解决你的问题,请参考以下文章

css3动画效果,如何设置呢?

css3圆环旋转效果动画怎么做

css3 实现动画效果,怎样使他无限循环动下去?

css3图片文字实现动画效果

利用CSS3制作淡入淡出动画效果

CSS3动画