环形进度条

使用场景

用于加载页面,环形进度条,中间放一个圆形图片,动态加载一周

效果图

代码示例

<template>
	<view class="container">
		<!-- Canvas 画布 -->
		<canvas id="progressCanvas" class="progress-canvas" canvas-id="progressCanvas"></canvas>
		<!-- 中心的图片 -->
		<image class="center-image" src="../../static/logo.png" mode="aspectFill" />
	</view>
</template>

<script>
	export default {
		data() {
			return {
				currentProgress: 0, // 当前进度值
				targetProgress: 100, // 目标进度值
			};
		},
		mounted() {
			this.startAnimation(this.targetProgress); // 页面加载时自动开始动画
		},
		methods: {
			// 绘制环形进度条
			drawProgressCircle() {
				const ctx = uni.createCanvasContext('progressCanvas', this);
				const width = 200; // canvas宽度
				const height = 200; // canvas高度
				const radius = 80; // 圆的半径
				const lineWidth = 10; // 进度条宽度

				// 进度条的颜色和背景色
				const progressColor = '#4caf50';
				const bgColor = '#ddd';

				// 画布中心坐标
				const centerX = width / 2;
				const centerY = height / 2;

				// 清除画布,重新绘制
				ctx.clearRect(0, 0, width, height);

				// 绘制背景圆环(只占据进度条的背景)
				ctx.beginPath();
				ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI); // 绘制一个完整的圆环
				ctx.setLineWidth(lineWidth); // 设置线宽,确保它是环形的
				ctx.setStrokeStyle(bgColor); // 背景色
				ctx.setLineCap('round'); // 设置圆角
				ctx.stroke();

				// 绘制进度圆弧
				ctx.beginPath();
				const startAngle = -Math.PI / 2; // 从上面开始画
				const endAngle = startAngle + (2 * Math.PI) * (this.currentProgress / 100);
				ctx.arc(centerX, centerY, radius, startAngle, endAngle);
				ctx.setLineWidth(lineWidth); // 设置进度条线宽
				ctx.setStrokeStyle(progressColor);
				ctx.setLineCap('round'); // 设置圆角
				ctx.stroke();

				// 绘制完毕,渲染画布
				ctx.draw();
			},
			// 启动进度条动画
			startAnimation(targetProgress) {
				this.targetProgress = targetProgress;
				this.animateProgress(0); // 从 0 开始动画
			},
			// 动画递归函数
			animateProgress(progress) {
				if (progress >= this.targetProgress) {
					this.currentProgress = this.targetProgress; // 确保最终到达目标进度
					this.drawProgressCircle(); // 最后一次绘制
					return;
				}

				this.currentProgress = progress; // 更新当前进度
				this.drawProgressCircle(); // 更新进度条显示

				// 增加进度,控制动画速度
				const increment = 1; // 每次更新 1%
				const delay = 10; // 更新频率,10 毫秒

				// 使用 setTimeout 递归调用
				setTimeout(() => {
					this.animateProgress(progress + increment); // 递归更新
				}, delay);
			}
		},
		beforeDestroy() {
			// 清除动画,防止内存泄漏
			if (this.animationFrameId) {
				clearTimeout(this.animationFrameId);
			}
		}
	};
</script>

<style scoped>
	.container {
		display: flex;
		justify-content: center;
		align-items: center;
		height: 100vh;
		flex-direction: column;
		position: relative
	}

	.progress-canvas {
		width: 200px;
		height: 200px;
	}

	.center-image {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 50px;
		height: 50px;
		transform: translate(-50%, -50%);
		/* 图片居中 */
		border-radius: 50%;
		/* 圆形图片 */
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值