react-countup

地址

https://github.com/glennreyes/react-countup
https://www.npmjs.com/package/react-countup

效果

react-countup.gif

Ant Motion(动效组件)

地址

单元素动画 - 数值变化 - Ant Motion

效果

数值变化.gif

纯 CSS 实现数字动画

https://css-tricks.com/animating-number-counters/
要写一个数字从 0-100 增长的动画效果,可能首先会想到用 setInterval,但是其实你可以试试 New School 的 CSS 解决方案。

示例一(手动触发)

css 数字动画.gif

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. <style>
  9. @property --num {
  10. syntax: '<integer>';
  11. initial-value: 0;
  12. inherits: false;
  13. }
  14. div {
  15. transition: --num 5s;
  16. counter-set: num var(--num);
  17. font: 800 40px system-ui;
  18. }
  19. div::after {
  20. content: counter(num);
  21. }
  22. div:hover {
  23. --num: 100;
  24. }
  25. body {
  26. margin: 2rem;
  27. }
  28. </style>
  29. </head>
  30. <body>
  31. Hover the number.
  32. <div></div>
  33. </body>
  34. </html>

示例二(也可以用于 @keyframes 自动触发)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. <style>
  9. @property --num {
  10. syntax: '<integer>';
  11. initial-value: 0;
  12. inherits: false;
  13. }
  14. div {
  15. animation: counter 5s infinite alternate ease-in-out;
  16. counter-reset: num var(--num);
  17. font: 800 40px system-ui;
  18. padding: 2rem;
  19. }
  20. div::after {
  21. content: counter(num);
  22. }
  23. @keyframes counter {
  24. from {
  25. --num: 0;
  26. }
  27. to {
  28. --num: 100;
  29. }
  30. }
  31. </style>
  32. </head>
  33. <body>
  34. <div></div>
  35. </body>
  36. </html>

示例三(携带小数)

css 数字小数动画.gif

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. <style>
  9. @property --percent {
  10. syntax: '<number>';
  11. initial-value: 0;
  12. inherits: false;
  13. }
  14. @property --temp {
  15. syntax: '<number>';
  16. initial-value: 0;
  17. inherits: false;
  18. }
  19. @property --v1 {
  20. syntax: '<integer>';
  21. initial-value: 0;
  22. inherits: false;
  23. }
  24. @property --v2 {
  25. syntax: '<integer>';
  26. initial-value: 0;
  27. inherits: false;
  28. }
  29. div {
  30. font: 800 40px monospace;
  31. padding: 2rem;
  32. transition: --percent 1s;
  33. --temp: calc(var(--percent) * 100);
  34. --v1: max(var(--temp) - 0.5, 0);
  35. --v2: max((var(--temp) - var(--v1)) * 100 - 0.5, 0);
  36. counter-reset: v1 var(--v1) v2 var(--v2);
  37. }
  38. div::before {
  39. content: counter(v1) '.' counter(v2, decimal-leading-zero) '%';
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <div></div>
  45. <script>
  46. const genNumber = () => {
  47. document
  48. .querySelector('div')
  49. .style.setProperty('--percent', Math.random());
  50. };
  51. setInterval(genNumber, 2000);
  52. setTimeout(genNumber);
  53. </script>
  54. </body>
  55. </html>