liyongli há 2 anos atrás
pai
commit
f8c6b90718

+ 11 - 0
src/api/SilkRoadSpringGala.js

@@ -135,3 +135,14 @@ export function getGiftList(data) {
       data,
     });
 }
+
+// 获得黄帝陵祭祖大典书法大赛报名人数
+export function getTotalNum(data) {
+    return ajax({
+      url: "https://shuhua.smcic.net/shuhua/total",
+      method: "GET",
+      urlType: "default",
+      header:{},
+      data,
+    });
+}

+ 5 - 0
src/components/counto/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/counto/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/counto/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: 0
+    },
+    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 = 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;
+    }
+  },
+  unmounted() {
+    cancelAnimationFrame(this.rAF)
+  }
+};
+</script>

+ 43 - 13
src/view/CalligraphyAndPaintingCompetition/index.vue

@@ -1,5 +1,12 @@
 <template>
   <div class="CalligraphyAndPaintingCompetition">
+    <div class="total">
+        已有
+        <span class="num">
+            <countTo :startVal="0" :endVal="total" :duration="3000"></countTo>
+        </span>
+      人报名
+    </div>
     <div class="bottom">
       <div class="bottom_item">
         <div class="btn" @click="toDetail = true">活动详情</div>
@@ -7,9 +14,6 @@
       <div class="bottom_item" style="flex: 3">
         <div class="btn" @click="tougao">我要投稿</div>
       </div>
-      <div class="bottom_item">
-        <div class="btn">我的作品</div>
-      </div>
     </div>
 
     <van-overlay
@@ -88,6 +92,8 @@ import {
   isAndroid,
   isWechat,
 } from '../../utils/isTerminal';
+import countTo from '@/components/counto/vue-countTo.vue';
+import { getTotalNum } from '@/api/SilkRoadSpringGala.js';
 /**
  * window.$originData.orginParames.title 页面标题
  * window.$originData.orginParames.parameters 固定参数值
@@ -97,7 +103,11 @@ import logoImage from '@/assets/img/logp.png';
 const toShanshipin = ref(false);
 const toDetail = ref(false);
 const showWixin = ref(false);
-
+const total = ref(0);
+tot();
+window.setInterval(() => {
+    tot();
+}, 5000);
 function getDownloadUrl() {
   let url = 'https://ssp.sxtvs.com.cn';
   if (isIpad || isIpod || isIphone)
@@ -119,14 +129,15 @@ function toShanshipinFunc() {
 }
 
 function tougao() {
-    if(!window.$shanshipin) return toShanshipin.value = true;
-  const url = "https://ssp-api.sxtvs.com.cn/tapi/form/index.html?ChannelID=20441",
-        contentId = "",
-        shareTitle = "",
-        shareSummary = "",
-        shareIcon = "",
-        shareUrl = "";
-  if (isIphone||isIpad||isIpod) {
+  if (!window.$shanshipin) return (toShanshipin.value = true);
+  const url =
+      'https://ssp-api.sxtvs.com.cn/tapi/form/index.html?ChannelID=20441',
+    contentId = '',
+    shareTitle = '',
+    shareSummary = '',
+    shareIcon = '',
+    shareUrl = '';
+  if (isIphone || isIpad || isIpod) {
     try {
       window.webkit.messageHandlers.TideAppStartNewsDetail.postMessage([
         url,
@@ -137,7 +148,7 @@ function tougao() {
         shareUrl,
       ]);
     } catch (e) {
-        console.log(e)
+      console.log(e);
     }
   } else {
     try {
@@ -153,7 +164,12 @@ function tougao() {
       console.log(e);
     }
   }
+}
 
+function tot() {
+  getTotalNum().then(r => {
+    total.value = r || 0;
+  });
 }
 </script>
 <style lang="scss">
@@ -256,5 +272,19 @@ function tougao() {
     width: 100vw;
     height: 100vh;
   }
+
+  .total{
+    color: #fff;
+    position: absolute;
+    top: 50%;
+    left:50%;
+    transform: translate(-50%, -50%);
+
+    .num{
+        background-color: rgba(0, 0, 0, 0.4);
+        border-radius: 3px;
+        padding: .5em;
+    }
+  }
 }
 </style>