From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 28 五月 2025 16:48:52 +0800
Subject: [PATCH] 初始化项目

---
 uview-ui/components/u-count-to/u-count-to.vue |  241 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 241 insertions(+), 0 deletions(-)

diff --git a/uview-ui/components/u-count-to/u-count-to.vue b/uview-ui/components/u-count-to/u-count-to.vue
new file mode 100644
index 0000000..053dc5f
--- /dev/null
+++ b/uview-ui/components/u-count-to/u-count-to.vue
@@ -0,0 +1,241 @@
+<template>
+	<view
+		class="u-count-num"
+		:style="{
+			fontSize: fontSize + 'rpx',
+			fontWeight: bold ? 'bold' : 'normal',
+			color: color
+		}"
+	>
+		{{ displayValue }}
+	</view>
+</template>
+
+<script>
+/**
+ * countTo 鏁板瓧婊氬姩
+ * @description 璇ョ粍浠朵竴鑸敤浜庨渶瑕佹粴鍔ㄦ暟瀛楀埌鏌愪竴涓�肩殑鍦烘櫙锛岀洰鏍囪姹傛槸涓�涓�掑鐨勫�笺��
+ * @tutorial https://www.uviewui.com/components/countTo.html
+ * @property {String Number} start-val 寮�濮嬪��
+ * @property {String Number} end-val 缁撴潫鍊�
+ * @property {String Number} duration 婊氬姩杩囩▼鎵�闇�鐨勬椂闂达紝鍗曚綅ms锛堥粯璁�2000锛�
+ * @property {Boolean} autoplay 鏄惁鑷姩寮�濮嬫粴鍔紙榛樿true锛�
+ * @property {String Number} decimals 瑕佹樉绀虹殑灏忔暟浣嶆暟锛岃瀹樼綉璇存槑锛堥粯璁�0锛�
+ * @property {Boolean} use-easing 婊氬姩缁撴潫鏃讹紝鏄惁缂撳姩缁撳熬锛岃瀹樼綉璇存槑锛堥粯璁rue锛�
+ * @property {String} separator 鍗冧綅鍒嗛殧绗︼紝瑙佸畼缃戣鏄�
+ * @property {String} color 瀛椾綋棰滆壊锛堥粯璁�#303133锛�
+ * @property {String Number} font-size 瀛椾綋澶у皬锛屽崟浣峳px锛堥粯璁�50锛�
+ * @property {Boolean} bold 瀛椾綋鏄惁鍔犵矖锛堥粯璁alse锛�
+ * @event {Function} end 鏁板�兼粴鍔ㄥ埌鐩爣鍊兼椂瑙﹀彂
+ * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
+ */
+export default {
+	name: 'u-count-to',
+	props: {
+		// 寮�濮嬬殑鏁板�硷紝榛樿浠�0澧為暱鍒版煇涓�涓暟
+		startVal: {
+			type: [Number, String],
+			default: 0
+		},
+		// 瑕佹粴鍔ㄧ殑鐩爣鏁板�硷紝蹇呴』
+		endVal: {
+			type: [Number, String],
+			default: 0,
+			required: true
+		},
+		// 婊氬姩鍒扮洰鏍囨暟鍊肩殑鍔ㄧ敾鎸佺画鏃堕棿锛屽崟浣嶄负姣锛坢s锛�
+		duration: {
+			type: [Number, String],
+			default: 2000
+		},
+		// 璁剧疆鏁板�煎悗鏄惁鑷姩寮�濮嬫粴鍔�
+		autoplay: {
+			type: Boolean,
+			default: true
+		},
+		// 瑕佹樉绀虹殑灏忔暟浣嶆暟
+		decimals: {
+			type: [Number, String],
+			default: 0
+		},
+		// 鏄惁鍦ㄥ嵆灏嗗埌杈剧洰鏍囨暟鍊肩殑鏃跺�欙紝浣跨敤缂撴參婊氬姩鐨勬晥鏋�
+		useEasing: {
+			type: Boolean,
+			default: true
+		},
+		// 鍗佽繘鍒跺垎鍓�
+		decimal: {
+			type: [Number, String],
+			default: '.'
+		},
+		// 瀛椾綋棰滆壊
+		color: {
+			type: String,
+			default: '#303133'
+		},
+		// 瀛椾綋澶у皬
+		fontSize: {
+			type: [Number, String],
+			default: 50
+		},
+		// 鏄惁鍔犵矖瀛椾綋
+		bold: {
+			type: Boolean,
+			default: false
+		},
+		// 鍗冧綅鍒嗛殧绗︼紝绫讳技閲戦鐨勫垎鍓�(锟�23,321.05涓殑",")
+		separator: {
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			localStartVal: this.startVal,
+			displayValue: this.formatNumber(this.startVal),
+			printVal: null,
+			paused: false, // 鏄惁鏆傚仠
+			localDuration: Number(this.duration),
+			startTime: null, // 寮�濮嬬殑鏃堕棿
+			timestamp: null, // 鏃堕棿鎴�
+			remaining: null, // 鍋滅暀鐨勬椂闂�
+			rAF: null,
+			lastTime: 0 // 涓婁竴娆$殑鏃堕棿
+		};
+	},
+	computed: {
+		countDown() {
+			return this.startVal > this.endVal;
+		}
+	},
+	watch: {
+		startVal() {
+			this.autoplay && this.start();
+		},
+		endVal() {
+			this.autoplay && this.start();
+		}
+	},
+	mounted() {
+		this.autoplay && this.start();
+	},
+	methods: {
+		easingFn(t, b, c, d) {
+			return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
+		},
+		requestAnimationFrame(callback) {
+			const currTime = new Date().getTime();
+			// 涓轰簡浣縮etTimteout鐨勫敖鍙兘鐨勬帴杩戞瘡绉�60甯х殑鏁堟灉
+			const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
+			const id = setTimeout(() => {
+				callback(currTime + timeToCall);
+			}, timeToCall);
+			this.lastTime = currTime + timeToCall;
+			return id;
+		},
+
+		cancelAnimationFrame(id) {
+			clearTimeout(id);
+		},
+		// 寮�濮嬫粴鍔ㄦ暟瀛�
+		start() {
+			this.localStartVal = this.startVal;
+			this.startTime = null;
+			this.localDuration = this.duration;
+			this.paused = false;
+			this.rAF = this.requestAnimationFrame(this.count);
+		},
+		// 鏆傚畾鐘舵�侊紝閲嶆柊鍐嶅紑濮嬫粴鍔紱鎴栬�呮粴鍔ㄧ姸鎬佷笅锛屾殏鍋�
+		reStart() {
+			if (this.paused) {
+				this.resume();
+				this.paused = false;
+			} else {
+				this.stop();
+				this.paused = true;
+			}
+		},
+		// 鏆傚仠
+		stop() {
+			this.cancelAnimationFrame(this.rAF);
+		},
+		// 閲嶆柊寮�濮�(鏆傚仠鐨勬儏鍐典笅)
+		resume() {
+			this.startTime = null;
+			this.localDuration = this.remaining;
+			this.localStartVal = this.printVal;
+			this.requestAnimationFrame(this.count);
+		},
+		// 閲嶇疆
+		reset() {
+			this.startTime = null;
+			this.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 = this.requestAnimationFrame(this.count);
+			} else {
+				this.$emit('end');
+			}
+		},
+		// 鍒ゆ柇鏄惁鏁板瓧
+		isNumber(val) {
+			return !isNaN(parseFloat(val));
+		},
+		formatNumber(num) {
+			// 灏唍um杞负Number绫诲瀷锛屽洜涓哄叾鍊煎彲鑳戒负瀛楃涓叉暟鍊硷紝璋冪敤toFixed浼氭姤閿�
+			num = Number(num);
+			num = num.toFixed(Number(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 x1 + x2;
+		},
+		destroyed() {
+			this.cancelAnimationFrame(this.rAF);
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/style.components.scss";
+
+.u-count-num {
+	/* #ifndef APP-NVUE */
+	display: inline-flex;		
+	/* #endif */
+	text-align: center;
+}
+</style>

--
Gitblit v1.9.3