浏览代码

countTo引入

13127578837 1 年之前
父节点
当前提交
e029d307d1

+ 5 - 0
src/components/count-to/index.js

@@ -0,0 +1,5 @@
+import CountTo from './vue-countTo.vue';
+export default CountTo;
+if (typeof window !== 'undefined' && window.Vue) {
+  window.Vue.component('count-to', CountTo);
+}

+ 46 - 0
src/components/count-to/requestAnimationFrame.js

@@ -0,0 +1,46 @@
+let lastTime = 0
+const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀
+
+let requestAnimationFrame
+let cancelAnimationFrame
+
+const isServer = typeof window === 'undefined'
+if (isServer) {
+  requestAnimationFrame = function() {
+    return
+  }
+  cancelAnimationFrame = function() {
+    return
+  }
+} else {
+  requestAnimationFrame = window.requestAnimationFrame
+  cancelAnimationFrame = window.cancelAnimationFrame
+  let prefix
+    // 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
+  for (let i = 0; i < prefixes.length; i++) {
+    if (requestAnimationFrame && cancelAnimationFrame) { break }
+    prefix = prefixes[i]
+    requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']
+    cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']
+  }
+
+  // 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
+  if (!requestAnimationFrame || !cancelAnimationFrame) {
+    requestAnimationFrame = function(callback) {
+      const currTime = new Date().getTime()
+      // 为了使setTimteout的尽可能的接近每秒60帧的效果
+      const timeToCall = Math.max(0, 16 - (currTime - lastTime))
+      const id = window.setTimeout(() => {
+        callback(currTime + timeToCall)
+      }, timeToCall)
+      lastTime = currTime + timeToCall
+      return id
+    }
+
+    cancelAnimationFrame = function(id) {
+      window.clearTimeout(id)
+    }
+  }
+}
+
+export { requestAnimationFrame, cancelAnimationFrame }

+ 191 - 0
src/components/count-to/vue-countTo.vue

@@ -0,0 +1,191 @@
+<template>
+    <span>
+      {{displayValue}}
+    </span>
+</template>
+<script>
+import { requestAnimationFrame, cancelAnimationFrame } from './requestAnimationFrame.js'
+export default {
+  props: {
+    startVal: {
+      type: Number,
+      required: false,
+      default: 0
+    },
+    endVal: {
+      type: Number,
+      required: false,
+      default: 2017
+    },
+    duration: {
+      type: Number,
+      required: false,
+      default: 3000
+    },
+    autoplay: {
+      type: Boolean,
+      required: false,
+      default: true
+    },
+    decimals: {
+      type: Number,
+      required: false,
+      default: 0,
+      validator(value) {
+        return value >= 0
+      }
+    },
+    decimal: {
+      type: String,
+      required: false,
+      default: '.'
+    },
+    separator: {
+      type: String,
+      required: false,
+      default: ','
+    },
+    prefix: {
+      type: String,
+      required: false,
+      default: ''
+    },
+    suffix: {
+      type: String,
+      required: false,
+      default: ''
+    },
+    useEasing: {
+      type: Boolean,
+      required: false,
+      default: true
+    },
+    easingFn: {
+      type: Function,
+      default(t, b, c, d) {
+        return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
+      }
+    }
+  },
+  data() {
+    return {
+      localStartVal: this.startVal,
+      displayValue: this.formatNumber(this.startVal),
+      printVal: null,
+      paused: false,
+      localDuration: this.duration,
+      startTime: null,
+      timestamp: null,
+      remaining: null,
+      rAF: null
+    };
+  },
+  computed: {
+    countDown() {
+      return this.startVal > this.endVal
+    }
+  },
+  watch: {
+    startVal() {
+      if (this.autoplay) {
+        this.start();
+      }
+    },
+    endVal() {
+      if (this.autoplay) {
+        this.start();
+      }
+    }
+  },
+  mounted() {
+    if (this.autoplay) {
+      this.start();
+    }
+    this.$emit('mountedCallback')
+  },
+  methods: {
+    start() {
+      this.localStartVal = this.startVal;
+      this.startTime = null;
+      this.localDuration = this.duration;
+      this.paused = false;
+      this.rAF = requestAnimationFrame(this.count);
+    },
+    pauseResume() {
+      if (this.paused) {
+        this.resume();
+        this.paused = false;
+      } else {
+        this.pause();
+        this.paused = true;
+      }
+    },
+    pause() {
+      cancelAnimationFrame(this.rAF);
+    },
+    resume() {
+      this.startTime = null;
+      this.localDuration = +this.remaining;
+      this.localStartVal = +this.printVal;
+      requestAnimationFrame(this.count);
+    },
+    reset() {
+      this.startTime = null;
+      cancelAnimationFrame(this.rAF);
+      this.displayValue = this.formatNumber(this.startVal);
+    },
+    count(timestamp) {
+      if (!this.startTime) this.startTime = timestamp;
+      this.timestamp = timestamp;
+      const progress = timestamp - this.startTime;
+      this.remaining = this.localDuration - progress;
+
+      if (this.useEasing) {
+        if (this.countDown) {
+          this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)
+        } else {
+          this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
+        }
+      } else {
+        if (this.countDown) {
+          this.printVal = this.localStartVal - ((this.localStartVal - this.endVal) * (progress / this.localDuration));
+        } else {
+          this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
+        }
+      }
+      if (this.countDown) {
+        this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
+      } else {
+        this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
+      }
+
+      this.displayValue = this.formatNumber(this.printVal)
+      if (progress < this.localDuration) {
+        this.rAF = requestAnimationFrame(this.count);
+      } else {
+        this.$emit('callback');
+      }
+    },
+    isNumber(val) {
+      return !isNaN(parseFloat(val))
+    },
+    formatNumber(num) {
+      num = parseInt(num).toFixed(this.decimals);
+      num += '';
+      const x = num.split('.');
+      let x1 = x[0];
+      const x2 = x.length > 1 ? this.decimal + x[1] : '';
+      const rgx = /(\d+)(\d{3})/;
+      if (this.separator && !this.isNumber(this.separator)) {
+        while (rgx.test(x1)) {
+          x1 = x1.replace(rgx, '$1' + this.separator + '$2');
+        }
+      }
+      return this.prefix + x1 + x2 + this.suffix;
+    }
+  },
+  destroyed() {
+    cancelAnimationFrame(this.rAF)
+  }
+};
+</script>

+ 5 - 2
src/views/self-management.vue

@@ -68,6 +68,7 @@
                                                 >
                                                     {{ score.value }}
                                                     {{ score.mark }}
+                                                    
                                                 </span>
                                             </el-col>
                                             <el-col :span="24">
@@ -118,7 +119,8 @@
                                             display: 'block',
                                         }"
                                     >
-                                        {{ score.value }} {{ score.mark }}
+                                        <CountTo :startVal='0' :endVal=' score? score.value:0' :duration='3000'> {{   score.value || 0 }}</CountTo>
+                                        <!-- {{ score.mark }} -->
                                     </span>
                                     <span style="font-size: 0.175rem; color: #ffffff">
                                         {{ score.name }}
@@ -783,7 +785,7 @@ import shebei1 from "@c/shebei";
 import radarChart from "@c/radar";
 import gauge from "@c/gauge";
 import pie1 from "@c/pie";
-
+import CountTo from '@/components/count-to/index.js'
 import map from "@c/mixins/map-data1";
 // import map from "@c/mixins/map-gaode-public";
 
@@ -797,6 +799,7 @@ export default {
         gauge,
         pie1,
         disk,
+        CountTo
     },
     mixins: [linstener, map],
     data() {