js实现数字增长动画多种方案

1、简单函数方案

<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <body>
    <h1 id="numBox"></h1>
  </body>
  <script type="text/javascript">
	  function NumAutoPlusAnimation(baseNumber, finalNum) {
	      var step = (finalNum - baseNumber) / 20;//颗粒化可以控制速度
	      var count = baseNumber; // 计数器
	      var initial = 0;
	      var timer = setInterval(() => {
	        count = count + step;
	        if (count >= finalNum) {
	          clearInterval(timer);
	          count = finalNum;
	        }
	        var t = count.toFixed(2);
	        initial = t;
	        numBox.innerHTML = initial;
	      }, 30);
	    }
	    NumAutoPlusAnimation(0, 26.88);
   </script>
</html>

2、html页面countUp.js方案

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document-countUp-js</title>

    <script>
      //   var CountUp = function (
      //     target,
      //     startVal,
      //     endVal,
      //     decimals,
      //     duration,
      //     options
      //   ) {
      //     var self = this;
      //     self.version = function () {
      //       return "1.9.2";
      //     };
      //     self.options = {
      //       useEasing: true,
      //       useGrouping: true,
      //       separator: ",",
      //       decimal: ".",
      //       easingFn: easeOutExpo,
      //       formattingFn: formatNumber,
      //       prefix: "",
      //       suffix: "",
      //       numerals: [],
      //     };
      //     if (options && typeof options === "object") {
      //       for (var key in self.options) {
      //         if (options.hasOwnProperty(key) && options[key] !== null) {
      //           self.options[key] = options[key];
      //         }
      //       }
      //     }
      //     if (self.options.separator === "") {
      //       self.options.useGrouping = false;
      //     } else {
      //       self.options.separator = "" + self.options.separator;
      //     }
      //     var lastTime = 0;
      //     var vendors = ["webkit", "moz", "ms", "o"];
      //     for (
      //       var x = 0;
      //       x < vendors.length && !window.requestAnimationFrame;
      //       ++x
      //     ) {
      //       window.requestAnimationFrame =
      //         window[vendors[x] + "RequestAnimationFrame"];
      //       window.cancelAnimationFrame =
      //         window[vendors[x] + "CancelAnimationFrame"] ||
      //         window[vendors[x] + "CancelRequestAnimationFrame"];
      //     }
      //     if (!window.requestAnimationFrame) {
      //       window.requestAnimationFrame = function (callback, element) {
      //         var currTime = new Date().getTime();
      //         var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      //         var id = window.setTimeout(function () {
      //           callback(currTime + timeToCall);
      //         }, timeToCall);
      //         lastTime = currTime + timeToCall;
      //         return id;
      //       };
      //     }
      //     if (!window.cancelAnimationFrame) {
      //       window.cancelAnimationFrame = function (id) {
      //         clearTimeout(id);
      //       };
      //     }
      //     function formatNumber(num) {
      //       num = num.toFixed(self.decimals);
      //       num += "";
      //       var x, x1, x2, x3, i, l;
      //       x = num.split(".");
      //       x1 = x[0];
      //       x2 = x.length > 1 ? self.options.decimal + x[1] : "";
      //       if (self.options.useGrouping) {
      //         x3 = "";
      //         for (i = 0, l = x1.length; i < l; ++i) {
      //           if (i !== 0 && i % 3 === 0) {
      //             x3 = self.options.separator + x3;
      //           }
      //           x3 = x1[l - i - 1] + x3;
      //         }
      //         x1 = x3;
      //       }
      //       if (self.options.numerals.length) {
      //         x1 = x1.replace(/[0-9]/g, function (w) {
      //           return self.options.numerals[+w];
      //         });
      //         x2 = x2.replace(/[0-9]/g, function (w) {
      //           return self.options.numerals[+w];
      //         });
      //       }
      //       return self.options.prefix + x1 + x2 + self.options.suffix;
      //     }
      //     function easeOutExpo(t, b, c, d) {
      //       return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
      //     }
      //     function ensureNumber(n) {
      //       return typeof n === "number" && !isNaN(n);
      //     }
      //     self.initialize = function () {
      //       if (self.initialized) {
      //         return true;
      //       }
      //       self.error = "";
      //       self.d =
      //         typeof target === "string"
      //           ? document.getElementById(target)
      //           : target;
      //       if (!self.d) {
      //         self.error = "[CountUp] target is null or undefined";
      //         return false;
      //       }
      //       self.startVal = Number(startVal);
      //       self.endVal = Number(endVal);
      //       if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) {
      //         self.decimals = Math.max(0, decimals || 0);
      //         self.dec = Math.pow(10, self.decimals);
      //         self.duration = Number(duration) * 1000 || 2000;
      //         self.countDown = self.startVal > self.endVal;
      //         self.frameVal = self.startVal;
      //         self.initialized = true;
      //         return true;
      //       } else {
      //         self.error =
      //           "[CountUp] startVal (" +
      //           startVal +
      //           ") or endVal (" +
      //           endVal +
      //           ") is not a number";
      //         return false;
      //       }
      //     };
      //     self.printValue = function (value) {
      //       var result = self.options.formattingFn(value);
      //       if (self.d.tagName === "INPUT") {
      //         this.d.value = result;
      //       } else {
      //         if (self.d.tagName === "text" || self.d.tagName === "tspan") {
      //           this.d.textContent = result;
      //         } else {
      //           this.d.innerHTML = result;
      //         }
      //       }
      //     };
      //     self.count = function (timestamp) {
      //       if (!self.startTime) {
      //         self.startTime = timestamp;
      //       }
      //       self.timestamp = timestamp;
      //       var progress = timestamp - self.startTime;
      //       self.remaining = self.duration - progress;
      //       if (self.options.useEasing) {
      //         if (self.countDown) {
      //           self.frameVal =
      //             self.startVal -
      //             self.options.easingFn(
      //               progress,
      //               0,
      //               self.startVal - self.endVal,
      //               self.duration
      //             );
      //         } else {
      //           self.frameVal = self.options.easingFn(
      //             progress,
      //             self.startVal,
      //             self.endVal - self.startVal,
      //             self.duration
      //           );
      //         }
      //       } else {
      //         if (self.countDown) {
      //           self.frameVal =
      //             self.startVal -
      //             (self.startVal - self.endVal) * (progress / self.duration);
      //         } else {
      //           self.frameVal =
      //             self.startVal +
      //             (self.endVal - self.startVal) * (progress / self.duration);
      //         }
      //       }
      //       if (self.countDown) {
      //         self.frameVal =
      //           self.frameVal < self.endVal ? self.endVal : self.frameVal;
      //       } else {
      //         self.frameVal =
      //           self.frameVal > self.endVal ? self.endVal : self.frameVal;
      //       }
      //       self.frameVal = Math.round(self.frameVal * self.dec) / self.dec;
      //       self.printValue(self.frameVal);
      //       if (progress < self.duration) {
      //         self.rAF = requestAnimationFrame(self.count);
      //       } else {
      //         if (self.callback) {
      //           self.callback();
      //         }
      //       }
      //     };
      //     self.start = function (callback) {
      //       if (!self.initialize()) {
      //         return;
      //       }
      //       self.callback = callback;
      //       self.rAF = requestAnimationFrame(self.count);
      //     };
      //     self.pauseResume = function () {
      //       if (!self.paused) {
      //         self.paused = true;
      //         cancelAnimationFrame(self.rAF);
      //       } else {
      //         self.paused = false;
      //         delete self.startTime;
      //         self.duration = self.remaining;
      //         self.startVal = self.frameVal;
      //         requestAnimationFrame(self.count);
      //       }
      //     };
      //     self.reset = function () {
      //       self.paused = false;
      //       delete self.startTime;
      //       self.initialized = false;
      //       if (self.initialize()) {
      //         cancelAnimationFrame(self.rAF);
      //         self.printValue(self.startVal);
      //       }
      //     };
      //     self.update = function (newEndVal) {
      //       if (!self.initialize()) {
      //         return;
      //       }
      //       newEndVal = Number(newEndVal);
      //       if (!ensureNumber(newEndVal)) {
      //         self.error =
      //           "[CountUp] update() - new endVal is not a number: " + newEndVal;
      //         return;
      //       }
      //       self.error = "";
      //       if (newEndVal === self.frameVal) {
      //         return;
      //       }
      //       cancelAnimationFrame(self.rAF);
      //       self.paused = false;
      //       delete self.startTime;
      //       self.startVal = self.frameVal;
      //       self.endVal = newEndVal;
      //       self.countDown = self.startVal > self.endVal;
      //       self.rAF = requestAnimationFrame(self.count);
      //     };
      //     if (self.initialize()) {
      //       self.printValue(self.startVal);
      //     }
      //   };
    </script>
    <script src="https://unpkg.com/[email protected]/dist/countUp.min.js"></script>
  </head>
  <body>
    <div id="num1"></div>
    <div id="num2"></div>
    <button onclick="start()">增加+</button>
    <button onclick="reset()">重置</button>
  </body>
  <script>
    var options = {
      useEasing: true, // 过渡动画效果,默认ture
      useGrouping: true, // 千分位效果,例:1000->1,000。默认true
      separator: ",", // 使用千分位时分割符号
      decimal: ".", // 小数位分割符号
      prefix: "*", // 前置符号
      suffix: "", // 后置符号,可汉字
    };
    // new CountUp(target,startVal,endVal,decimals,duration,options)
    // dom节点, 初始值,  结束值, 小数位数, 过渡几秒 , 初始参数

    var num1 = new CountUp("num1", 0, 200, 2);
    var num2 = new CountUp("num2", 100, 399);

    function start() {
      console.log("start", num1);
      // 开始
      num1.start();
      num2.start();
    }
    function pause() {
      console.log("pause");
      // 暂停或继续
      num1.pauseResume();
    }
    function reset() {
      console.log("reset");
      // 重置初始值
      num1.reset();
    }
    function updata() {
      console.log("updata");
      // 重新赋值
      num1.update(888);
    }

    //滚动到当前元素执行start()
    let numDiv = document.querySelector("#num1");
    document.addEventListener("scroll", function (e) {
      let a =
        document.documentElement.scrollTop +
        window.innerHeight -
        numDiv.offsetTop;
      // if (a > 0) {
      //   num1.start();
      // }
    });
  </script>
</html>

3、vue中使用useTransition和countUp方案

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vue-Document</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://unpkg.com/@vueuse/shared"></script>
    <script src="https://unpkg.com/@vueuse/core"></script>
    <script src="https://unpkg.com/[email protected]/dist/countUp.min.js"></script>
  </head>
  <body>
    <div id="app">
      <span>{{message}}---count:{{count}}</span>
      <br />
      <button @click="count+=121">
        增加-useTransition--Count is: {{ Math.floor(output) }}
      </button>
      <div id="countup" ref="countupRef">1</div>
      <button @click="initCount">增加-CountUp:{{}}</button>
    </div>
    <script>
      const { createApp, ref, onMounted } = Vue;
      const { TransitionPresets, useTransition } = VueUse;
      createApp({
        setup() {
          const countupRef = ref(null);
          const message = ref("Hello vue!");
          const count = ref(0);
          const output = useTransition(count, {
            duration: 1000,
            transition: TransitionPresets.easeInOutCubic,
          });
          onMounted(() => {
            // console.log(countupRef.value);
          });
          const initCount = () => {
            num1 = new CountUp(countupRef.value, 2,100);
            num1.start();
          };
          return {
            message,
            count,
            output,
            initCount,
            countupRef
          };
        },
      }).mount("#app");
    </script>
  </body>
</html>

4、vue中使用vue-countup-v2方案

CountUp.js:https://github.com/inorganik/CountUp.js
vue-countup-v2:https://github.com/xlsdg/vue-countup-v2
安装

npm install --save countup.js vue-countup-v2

usage

<template>
  <div class="iCountUp">
    <ICountUp
      :delay="delay"
      :endVal="endVal"
      :options="options"
      @ready="onReady"
    />
  </div>
</template>

<script type="text/babel">
  import ICountUp from 'vue-countup-v2';
  export default {
    name: 'demo',
    components: {
      ICountUp
    },
    data() {
      return {
        delay: 1000,
        endVal: 120500,
        options: {
          useEasing: true,
          useGrouping: true,
          separator: ',',
          decimal: '.',
          prefix: '',
          suffix: ''
        }
      };
    },
    methods: {
      onReady: function(instance, CountUp) {
        const that = this;
        instance.update(that.endVal + 100);
      }
    }
  };
</script>

<style scoped>
  .iCountUp {
    font-size: 12em;
    margin: 0;
    color: #4d63bc;
  }
</style>

5、tweenjs方案

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document-tweenjs</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/20.0.0/tween.umd.js"></script>
    <style></style>
  </head>
  <body>
    <div id="box">0</div>
    <button class="btn">tweenjs增加+</button>
    <script>
      const box = document.getElementById("box"); // Get the element we want to animate.
      let data = { num: 0 };
      const tweenC = new TWEEN.Tween(data)
        .to({ num: 199 }, 1000)
        .easing(TWEEN.Easing.Quadratic.InOut)
        .onUpdate((a) => {
          num = Math.floor(data.num);
          console.log(num);
          box.innerText = num;
        })
        .start();

      function animate() {
        requestAnimationFrame(animate); // requestAnimationFrame可以看成setTimeout(animate, 17)
        tweenC.update();
      }
      // animate()
      const btn = document.querySelector(".btn");
      btn.addEventListener("click", function (e) {
        animate();
      });
    </script>
  </body>
</html>

你可能感兴趣的:(javascript,前端)