Ver Fonte

增加数字动态翻滚效果

mork há 2 semanas atrás
pai
commit
1dc5f78447

+ 231 - 0
src/components/AppVue/digitalScrollersComp.vue

@@ -0,0 +1,231 @@
+<template>
+  <div class="count-flop" :key="compKey">
+    <!--  -->
+    <div
+      :class="item !== '.' ? 'count-flop-box' : 'count-flop-point'"
+      v-for="(item, index) in value"
+      :key="index"
+    >
+      <div v-if="item !== '.'" class="count-flop-content" :class="['rolling_' + item]">
+        <div v-for="(item2, index2) in numberList" :key="index2" class="count-flop-num">
+          {{ item2 }}
+        </div>
+      </div>
+      <div v-else class="count-flop-content">.</div>
+    </div>
+    <!--  -->
+    <div v-if="suffix" class="count-flop-unit">{{ suffix }}</div>
+  </div>
+</template>
+ 
+<script setup>
+import { ref, watch, onMounted } from 'vue'
+ 
+const props = defineProps({
+  val: {
+    type: [Number, String],
+    default: 0,
+  },
+  suffix: {
+    type: String,
+    default: "",
+  },
+});
+ 
+// Data
+const value = ref([]);
+const numberList = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+const compKey = ref(0);
+ 
+// Watcher
+watch(
+  () => props.val,
+  (newVal) => {
+    value.value = newVal.toString().split("");
+    compKey.value += 1;
+  },
+  { immediate: true },
+);
+</script>
+ 
+<style scoped>
+.count-flop {
+  display: inline-block;
+  font-size: 0;
+  /* 可更改 */
+  height: 100px;
+  line-height: 100px;
+  font-size: 50px;
+  font-weight: 700;
+  color: #ffffff;
+}
+ 
+.count-flop > div {
+  position: relative;
+  display: inline-block;
+  overflow: hidden;
+  height: 100%;
+}
+ 
+.count-flop-box {
+  /* 可更改 */
+  margin-right: 5px;
+  width: 86px;
+  color: #ffffff;
+  background-color: rgba(6, 41, 78, 0.7);
+  border: 1px solid #2663a5;
+  /* box-shadow: 0 2px 5px #2663a5; */
+  /*
+  这里的高度要比上面height的少2px
+  */
+  line-height: 98px;
+  border-radius: 6px;
+}
+ 
+.count-flop-point {
+  /* 可更改 */
+  margin-right: 5px;
+  width: 10px;
+}
+ 
+.count-flop-content {
+  font-family: MicrosoftYaHei-Bold;
+  text-align: center;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  animation-fill-mode: forwards !important;
+}
+.rolling_0 {
+  animation: rolling_0 2.1s ease;
+}
+ 
+@keyframes rolling_0 {
+  from {
+    transform: translateY(-90%);
+  }
+  to {
+    transform: translateY(0);
+  }
+}
+ 
+.rolling_1 {
+  animation: rolling_1 3s ease;
+}
+ 
+@keyframes rolling_1 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-10%);
+  }
+}
+ 
+.rolling_2 {
+  animation: rolling_2 2.1s ease;
+}
+ 
+@keyframes rolling_2 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-20%);
+  }
+}
+ 
+.rolling_3 {
+  animation: rolling_3 3s ease;
+}
+ 
+@keyframes rolling_3 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-30%);
+  }
+}
+ 
+.rolling_4 {
+  animation: rolling_4 2.1s ease;
+}
+ 
+@keyframes rolling_4 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-40%);
+  }
+}
+ 
+.rolling_5 {
+  animation: rolling_5 3s ease;
+}
+ 
+@keyframes rolling_5 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-50%);
+  }
+}
+ 
+.rolling_6 {
+  animation: rolling_6 2.1s ease;
+}
+ 
+@keyframes rolling_6 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-60%);
+  }
+}
+ 
+.rolling_7 {
+  animation: rolling_7 3.1s ease;
+}
+ 
+@keyframes rolling_7 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-70%);
+  }
+}
+ 
+.rolling_8 {
+  animation: rolling_8 2.1s ease;
+}
+ 
+@keyframes rolling_8 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-80%);
+  }
+}
+ 
+.rolling_9 {
+  animation: rolling_9 3.6s ease;
+}
+ 
+@keyframes rolling_9 {
+  from {
+    transform: translateY(0);
+  }
+  to {
+    transform: translateY(-90%);
+  }
+}
+ 
+/* 其他 rolling_X 动画略 */
+</style>

+ 37 - 0
src/components/AppVue/numberScroll.vue

@@ -0,0 +1,37 @@
+<template>
+  <span ref="numberEl">{{ displayValue }}</span>
+</template>
+
+<script setup>
+import { ref, watch, onMounted } from 'vue'
+
+const props = defineProps({
+  value: { type: Number, default: 0 },
+  duration: { type: Number, default: 1500 },
+  easing: { type: Function, default: (t) => t * (2 - t) }
+})
+
+const displayValue = ref(0)
+const numberEl = ref(null)
+
+function animate(start, end) {
+  const startTime = performance.now()
+  const frame = (currentTime) => {
+    const elapsed = currentTime - startTime
+    const progress = Math.min(elapsed / props.duration, 1)
+    displayValue.value = Math.floor(start + (end - start) * props.easing(progress))
+    if (progress < 1) {
+      requestAnimationFrame(frame)
+    }
+  }
+  requestAnimationFrame(frame)
+}
+
+watch(() => props.value, (newVal, oldVal) => {
+  animate(oldVal, newVal)
+})
+
+onMounted(() => {
+  animate(0, props.value)
+})
+</script>

+ 9 - 2
src/components/yxgl/card.vue

@@ -2,7 +2,10 @@
   <div>
     <div class="leftInfo">
       <div class="leftInfo_title">{{ title }}</div>
-      <div class="leftInfo_value">{{ value }}</div>
+      <div class="leftInfo_value">
+        <!-- {{value}} -->
+        <NumberScroll :value="value" :duration="2000" />
+      </div>
       <div class="leftInfo_growth" :style="{ color: growthColors[upStatus + 1] }">
         <el-icon
           ><Top v-if="upStatus == 1" /><SemiSelect v-if="upStatus == 0" /><Bottom
@@ -21,8 +24,12 @@
 </template>
 
 <script>
+import NumberScroll from '@/components/AppVue/numberScroll.vue'
 export default {
   name: "card",
+  components: {
+    NumberScroll
+  },
   props: {
     title: {
       type: String,
@@ -30,7 +37,7 @@ export default {
     },
     value: {
       type: String,
-      default: "-",
+      default: "0",
     },
     growth: {
       type: String,

+ 29 - 18
src/views/HomePage.vue

@@ -8,14 +8,17 @@
           <div class="part1-1-1">
             <div class="number-container">
               <span class="text">调用总数</span>
-              <span v-for="(num, index) in totalCall" :key="index">
+               <digitalScrollersComp :val="totalCallNumber" />
+              <!-- <span v-for="(num, index) in totalCall" :key="index">
                 <span v-if="num.indexOf(',') > -1">
                   <span class="separator">,</span>
                 </span>
                 <span v-else>
-                  <span class="number-item">{{ num }}</span>
+                  <span class="number-item">
+                    <NumberScroll :value="num" :duration="2000" />
+                  </span>
                 </span>
-              </span>
+              </span> -->
               <span class="text">次</span>
             </div>
           </div>
@@ -24,7 +27,7 @@
               <div class="line"></div>
               <div>
                 <span class="text1">昨日调用量</span>
-                <span class="count">{{ lastDayCall }}</span>
+                <span class="count"><NumberScroll :value="lastDayCall" :duration="2000" /></span>
                 <span class="text2">次</span>
               </div>
               <div class="line"></div>
@@ -36,15 +39,15 @@
     <div class="darkblue-background">
       <div class="row">
         <div>
-          <div class="strong-data blue ">{{ unitNum }}个</div>
+          <div class="strong-data blue "><NumberScroll :value="unitNum" :duration="2000" />个</div>
           <div class="font middle">授权委办数</div>
         </div>
         <div>
-          <div class="strong-data blue ">{{ appNum }}个</div>
+          <div class="strong-data blue "><NumberScroll :value="appNum" :duration="2000" />个</div>
           <div class="font middle">授权应用数</div>
         </div>
         <div>
-          <div class="strong-data blue ">{{ userNum }}个</div>
+          <div class="strong-data blue "><NumberScroll :value="userNum" :duration="2000" />个</div>
           <div class="font middle">授权用户数</div>
         </div>
       </div>
@@ -67,19 +70,19 @@
           </div>
           <div class="grid-2x2">
             <div class="lighter-container middle-container">
-              <div class="strong-data  blue">{{ weekCall }}</div>
+              <div class="strong-data  blue"><NumberScroll :value="weekCall" :duration="2000" /></div>
               <div class="title-sub ">近一周总调用</div>
             </div>
             <div class="lighter-container middle-container">
-              <div class="strong-data  blue">{{ monthCall }}</div>
+              <div class="strong-data  blue"><NumberScroll :value="monthCall" :duration="2000" /></div>
               <div class="title-sub ">近一月总调用</div>
             </div>
             <div class="lighter-container middle-container">
-              <div class="strong-data  blue">{{ seasonCall }}</div>
+              <div class="strong-data  blue"><NumberScroll :value="seasonCall" :duration="2000" /></div>
               <div class="title-sub ">近三月总调用</div>
             </div>
             <div class="lighter-container middle-container">
-              <div class="strong-data  blue">{{ yearCall }}</div>
+              <div class="strong-data  blue"><NumberScroll :value="yearCall" :duration="2000" /></div>
               <div class="title-sub ">近一年总调用</div>
             </div>
           </div>
@@ -168,15 +171,15 @@
 
       <div class="row" style="margin-top: 90px;">
         <div>
-          <div class="strong-data blue ">365个</div>
+          <div class="strong-data blue "><NumberScroll :value="365" :duration="2000" />个</div>
           <div class="font middle">地名地址</div>
         </div>
         <div>
-          <div class="strong-data blue ">366个</div>
+          <div class="strong-data blue "><NumberScroll :value="366" :duration="2000" />个</div>
           <div class="font middle">坐标转换</div>
         </div>
         <div>
-          <div class="strong-data blue ">367个</div>
+          <div class="strong-data blue "><NumberScroll :value="367" :duration="2000" />个</div>
           <div class="font middle">地图服务</div>
         </div>
       </div>
@@ -462,13 +465,20 @@ import * as echarts from "echarts";
 import moment from "moment";
 let chart1 = null;
 let chartMultiLevelUse = null;
+import NumberScroll from '@/components/AppVue/numberScroll.vue'
+import digitalScrollersComp from '@/components/AppVue/digitalScrollersComp.vue'
 
 export default {
   name: "Home",
+  components: {
+    NumberScroll,
+    digitalScrollersComp
+  },
   data() {
     return {
       lastDayCall: "0",
       totalCall: ["0", "0", "0", ",", "0", "0", "0"],
+      totalCallNumber: "0",
 
       serveNum: 0,
       userNum: 0,
@@ -589,6 +599,7 @@ export default {
     handleTotalCallNumber(num) {
       // 667507060
       let str = num.toString();
+      this.totalCallNumber = str;
       let strArr = str.split("").reverse();
       this.totalCall = [];
       for (let i = 0; i < strArr.length; i++) {
@@ -1317,10 +1328,10 @@ export default {
       overflow: hidden;
 
       .part1-1-1 {
-        height: 70px;
+        height: 100px;
         width: fit-content;
         margin: 0 auto;
-        margin-top: 30px;
+        // margin-top: 30px;
 
         .number-container {
           display: flex;
@@ -1354,8 +1365,8 @@ export default {
 
         .text {
           font-size: 24px;
-          line-height: 70px;
-          margin-right: 20px;
+          line-height: 100px;
+          padding: 0px 20px;
           color: #ffffff;
           font-weight: bold;
         }

+ 7 - 3
src/views/skmh/index.vue

@@ -38,7 +38,7 @@
               fit="cover"
             />
           </div>
-          <div class="stat-number">{{countData.total.service}}</div>
+          <div class="stat-number"><NumberScroll :value="countData.total.service" :duration="2000" /></div>
           <div class="stat-label">较上月增长{{countData.grown}}%</div>
         </div>
         <div class="stat-card card-2">
@@ -49,7 +49,7 @@
               fit="cover"
             />
           </div>
-          <div class="stat-number">{{countData.curMonth.service}}</div>
+          <div class="stat-number"><NumberScroll :value="countData.curMonth.service" :duration="2000" /></div>
           <div class="stat-label">本月新增服务</div>
         </div>
         <div class="stat-card card-3">
@@ -60,7 +60,7 @@
               fit="cover"
             />
           </div>
-          <div class="stat-number">{{countData.total.username}}</div>
+          <div class="stat-number"><NumberScroll :value="countData.total.username" :duration="2000" /></div>
           <div class="stat-label">本周新增{{countData.curWeek.username}}人</div>
         </div>
       </div>
@@ -213,8 +213,12 @@ import * as echarts from 'echarts'
 import appCenter from "@/api/appCenter";
 import { countUserList,coutService,totalCountGroupByTime,countUserDataByAutoTime } from "@/api/count";
 import moment from "moment";
+import NumberScroll from '@/components/AppVue/numberScroll.vue'
 export default {
   name: 'SpatialTemporalPortal',
+  components: {
+    NumberScroll
+  },
   data() {
     return {
       deviceChart: null,

+ 4 - 4
src/views/yxgl/StatisticalAnalysis.vue

@@ -261,7 +261,7 @@ export default {
       TopCardDatas: [
         {
           name: "委办总数",
-          value: "-",
+          value: "0",
           growth: "--",
           iconColor: "#2563db",
           iconName: "OfficeBuilding",
@@ -269,7 +269,7 @@ export default {
         },
         {
           name: "系统总数",
-          value: "-",
+          value: "0",
           growth: "--",
           iconColor: "#16a34a",
           iconName: "WalletFilled",
@@ -277,7 +277,7 @@ export default {
         },
         {
           name: "服务总数",
-          value: "-",
+          value: "0",
           growth: "--",
           iconColor: "#9333ea",
           iconName: "TrendCharts",
@@ -285,7 +285,7 @@ export default {
         },
         {
           name: "服务调用总数",
-          value: "-",
+          value: "0",
           growth: "--",
           iconColor: "#ca8a04",
           iconName: "TrendCharts",

+ 5 - 2
src/views/yygl/monitor/index.vue

@@ -10,7 +10,7 @@
           </div>
           <div class="stat-content">
             <div class="stat-label">{{ item.name }}</div>
-            <div class="stat-number">{{ item.value }} 个</div>
+            <div class="stat-number"><NumberScroll :value="item.value" :duration="2000" /> 个</div>
           </div>
         </div>
         <!-- <div class="stat-card">
@@ -153,9 +153,12 @@ import * as echarts from "echarts";
 import appCenter from "@/api/appCenter";
 import { topApp,countAppInfo } from "@/api/count";
 import moment from "moment";
+import NumberScroll from '@/components/AppVue/numberScroll.vue'
 export default {
   name: "ApplicationMonitor",
-  components: {},
+  components: {
+    NumberScroll
+  },
   data() {
     return {
       statusChart: null,