使用svg实现环形进度条效果,环内显示百分数

效果图

在这里插入图片描述

创建组件

<template>
	<view :style="[fsObj]">
		<view class="progress-circle1" v-if="progressType == 1 || isFloat">
			<svg>
				<circle stroke="var(--inactive-color)" />
				<circle stroke="var(--color)" class="progress-value"
					style="stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" />
			</svg>
		</view>
		<view class="progress-circle2" v-else>
			<svg>
				<circle stroke="var(--inactive-color)" />
				<circle stroke="var(--color)" class="progress-value"
					style="stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" />
			</svg>
		</view>
	</view>
</template>

<script>
	// type:1 保留小数点后两位
	// type:2 整数不显示小数点,小数保留小数点后两位
	export default {
		name: "progress-circle",
		props: {
			percent: {
				type: Number,
				default: 0
			},
			size: {
				type: String,
				default: '72px'
			},
			borderWidth: {
				type: String,
				default: '9px'
			},
			color: {
				type: String,
				default: '#E54242'
			},
			inactiveColor: {
				type: String,
				default: '#ccc'
			},
			type: {
				type: String,
				default: 1
			}
		},
		data() {
			return {
				fsObj: {
					'--percent': 0, // 百分数
					'--int': 0, // 整数部分
					'--floatInt': 0, // 小数部分
					'--size': '72px', // 图形大小
					'--border-width': '9px', // 环宽(粗细)
					'--color': '#E54242', // 主色
					'--inactive-color': '#ccc' // 辅助色
				},
				progressType: 1,
				isFloat: false
			};
		},
		watch: {
			percent: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.fsObj['--percent'] = newVal
						this.fsObj['--int'] = Math.floor(newVal)
						this.fsObj['--floatInt'] = parseInt((newVal - Math.floor(newVal))*100)
						this.isFloat = parseInt((newVal - Math.floor(newVal))*100) > 0 ? true : false
					}
				},
				immediate: true
			},
			size: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.fsObj['--size'] = newVal
					}
				},
				immediate: true
			},
			borderWidth: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.fsObj['--border-width'] = newVal
					}
				},
				immediate: true
			},
			color: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.fsObj['--color'] = newVal
					}
				},
				immediate: true
			},
			inactiveColor: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.fsObj['--inactive-color'] = newVal
					}
				},
				immediate: true
			},
			type: {
				handler(newVal, oldVal) {
					if(newVal) {
						this.progressType = Number(newVal)
					}
				},
				immediate: true
			}
		},
		methods: {
			
		}
	}
</script>

<style lang="scss">
	.progress-circle1, .progress-circle2 {
		position: relative;
		width: var(--size);
		height: var(--size);
		border-radius: 50%;
	}

	/* 百分数文本 */
	.progress-circle1::before {
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		counter-reset: progress1 var(--int) progress2 var(--floatInt);
		content: counter(progress1) '.' counter(progress2, decimal-leading-zero) '%';
		white-space: nowrap;
		font-size: 24rpx;
	}
	
	.progress-circle2::before {
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		counter-reset: progress var(--int);
		content: counter(progress) '%';
		white-space: nowrap;
		font-size: 24rpx;
	}

	/* SVG 容器 */
	.progress-circle1>svg, .progress-circle2>svg {
		width: 100%;
		height: 100%;
		transform: rotate(-90deg);
	}

	/* 进度条圆环 */
	.progress-circle1 circle, .progress-circle2 circle {
		--r: calc((var(--size) - var(--border-width)) / 2);

		cx: calc(var(--size) / 2);
		cy: calc(var(--size) / 2);
		r: var(--r);
		fill: none;
		stroke-width: var(--border-width);
		stroke-linecap: round;
		transition: stroke-dasharray .4s linear, stroke .3s;
	}

	/* 优化:进度为0时隐藏进度条 */
	.progress-value {
		opacity: var(--percent);
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值