CSS 动画:数字递增效果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27956723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:54:50  来源:igfitidea点击:

CSS Animation: Number increment effect

cssanimationcss-animations

提问by ditto

I'm wanting to get that animation effect when numbers change quickly, example: http://jsbin.com/kevalutupe/1/

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

I'm wanting to do this CSS alone (I know how to code it in JS), I don't want to use JS as I feel hammering the DOM isn't the best solution. Is this at all possible with CSS?

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

I'm not fussed about the numbers actually incrementing correctly, I'm just after the effect.

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

回答by Harry

The number spinning effect is most definitely possible using CSS3 animations and what's better you can also set the end-point using a small bit of JS and actually get the whole functionality.

使用 CSS3 动画绝对可以实现数字旋转效果,而且您​​还可以使用少量 JS 设置终点并实际获得整个功能。

Method Explanation:

方法说明:

  1. A divis created such that it will always display only one number by setting its height and width as 1em. Overflow of the divis set to hidden so as to make only one line visible.
  2. Within this diva spancontaining all the numbers from 1 to 0 is created and is positioned relative to the parent.
  3. Initial position of the spanis at 0px or 0em but during the animationthe top position is changed so that the spangives the impression of being moved upwards. Because the divcan display only one number at a time, it gives the spinning effect (or the effect of the other numbers disappearing).
  4. Final position is achieved by setting a fixed top position to each of the spanelements. 0em means the 1st line is visible (number 1), -2em means the third line becomes visible (number 3) and so on.
  5. Increasing or decreasing the animation duration will make the spin effect happen quickly or slowly. The animation iteration count is set to 5 to produce an illusion that the spinner is spinning multiple times.
  1. div通过将其高度和宽度设置为 1em,A被创建为始终只显示一个数字。的溢出div设置为隐藏,以便仅显示一行。
  2. 在这个包含从 1 到 0 的所有数字的divaspan中创建并相对于父级定位。
  3. 的初始位置为span0px 或 0em,但在animation顶部位置发生变化时,span给人一种向上移动的印象。因为一次div只能显示一个数字,所以它给出了旋转效果(或其他数字消失的效果)。
  4. 最终位置是通过为每个span元素设置一个固定的顶部位置来实现的。0em 表示第一行可见(编号 1),-2em 表示第三行可见(编号 3),依此类推。
  5. 增加或减少动画持续时间将使旋转效果快速或缓慢发生。动画迭代计数设置为 5 以产生旋转器多次旋转的错觉。

Note:Using this method, the spin will look like going the whole circle every-time and not like the JSBin sample in question where a 3 to 4 for the first digit would be just a single step and not a full circle.

注意:使用这种方法,每次旋转看起来都像是绕了一圈,而不是像有问题的 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>



The below is a sample with JavaScript where the animation effect is achieved through CSS but the triggering of the animation and the setting of the endpoint is achieved using JavaScript.

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

The JS code is pretty much self explanatory. All we are doing is the following:

JS 代码几乎是不言自明的。我们所做的一切如下:

  1. Create a listener for the click event of the button and within it we add the animateclass to all the spanelements which are part of this animation effect. This is because we want the animation to happen only when the button is clicked.
  2. When the animation ends (or the spin is complete), we set the topproperty of each spanto some random number. This would mean that each span will have a different number displayed.
  3. On the end of the animation we are also calling another function to remove the animateclass so that when we click the button again the animation can start all over again.
  1. 为按钮的单击事件创建一个侦听器,并在其中将animate类添加到span作为此动画效果一部分的所有元素。这是因为我们希望动画仅在单击按钮时发生。
  2. 当动画结束(或旋转完成)时,我们将top每个的属性设置span为某个随机数。这意味着每个跨度将显示不同的数字。
  3. 在动画结束时,我们还调用另一个函数来删除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>



Version 2:(with only a number increment effect instead of a spinning effect)

版本2:(只有数字增量效果而不是旋转效果)

This is created using largely the same code as the previous one but unlike the previous one where the animationmakes the movement from one number to another a gradual one (and thereby producing a spin effect), here the animation makes the movement more like a sudden jump from one number to another and thereby produces just an increment effect.

这是使用与前一个大致相同的代码创建的,但与前一个不同,前一个animation使从一个数字到另一个数字的运动逐渐变成一个(从而产生旋转效果),这里的动画使运动更像是突然跳跃从一个数字到另一个数字,从而仅产生增量效果。

The jump is achieved by maintaining the topposition the same till its just about time to move to the next (that is, the topis set to be 0emtill 9.9% of the animation but at 10% it suddenly changes to -1em).

跳转是通过保持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>