uniapp中环状进度条

news2024/11/17 19:30:12

 调用插件:

	<circle-progress-bar :pro="84/100" :border_back_color="'#297DFE'" :border_color="'#FB8F23'">
		{{84}}%
	</circle-progress-bar>

 添加插件引用:

<script>
	import CircleProgressBar from '../../components/circle-progress-bar/circle-progress-bar.vue'

	export default {
		components: {
			Axxx,
			CircleProgressBar,
		},

</script>

circle-progress-bar.vue

<template>
	<view class="circle-progress-bar" 
	:style="{
		width: sunit(size),
		height: sunit(size),
	}">
		<view class="circle" :change:prop="animateModule.pro" :prop="cpro"
		:data-animate="animate"
		:style="{
			transform: `rotate(${start * 360 + 45}deg)`,
			border: `${sunit(border_width)} solid ${border_color}`,
		}">
		</view>
		<view class="bg" v-if="background"
		:style="{
			background: background,
		}"></view>
		<view class="border-back" v-if="border_back_color"
		:style="{
			border: `calc(${sunit(border_width)} - 1px) solid ${border_back_color}`
		}"></view>
		<view class="center">
			<slot :pro="cpro"></slot>
		</view>
	</view>
</template>

<script module="animateModule" lang="wxs">
	var Timing = {
		easeIn: function easeIn(pos) {
			return Math.pow(pos, 3);
		},
		easeOut: function easeOut(pos) {
			return Math.pow(pos - 1, 3) + 1;
		},
		easeInOut: function easeInOut(pos) {
			if ((pos /= 0.5) < 1) {
				return 0.5 * Math.pow(pos, 3);
			} else {
				return 0.5 * (Math.pow(pos - 2, 3) + 2);
			}
		},
		linear: function linear(pos) {
			return pos;
		}
	};

	//#ifdef MP
	function setTimeout(t, cb, d) {
		if (d > 0) {
			var s = getDate().getTime();
			var fn = function () {
				if (getDate().getTime() - s > d) {
					cb && cb();
				} else
					t.requestAnimationFrame(fn);
			}
			fn();
		}
		else
			cb && cb();
	}
	//#endif

	function Animation(opts) {
		opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
		opts.timing = opts.timing || 'linear';
		var delay = 17;

		function createAnimationFrame() {
			if (typeof setTimeout !== 'undefined') {
				return function(step, delay) {
					//#ifndef MP
					setTimeout(function() {
						var timeStamp = +new Date();
						step(timeStamp);
					}, delay);
					//#endif
					//#ifdef MP
					setTimeout(opts.instance, function () {
						var timeStamp = getDate()
						step(timeStamp);
					}, delay)
					//#endif
				};
			} else if (typeof requestAnimationFrame !== 'undefined') {
				return requestAnimationFrame;
			} else {
				return function(step) {
					step(null);
				};
			}
		};
		var animationFrame = createAnimationFrame();
		var startTimeStamp = null;
		var _step = function step(timestamp) {
			if (timestamp === null) {
				opts.onProcess && opts.onProcess(1);
				opts.onAnimationFinish && opts.onAnimationFinish();
				return;
			}
			if (startTimeStamp === null) {
				startTimeStamp = timestamp;
			}
			if (timestamp - startTimeStamp < opts.duration) {
				var process = (timestamp - startTimeStamp) / opts.duration;
				var timingFunction = Timing[opts.timing];
				process = timingFunction(process);

				opts.onProcess && opts.onProcess(process);
				animationFrame(_step, delay);
			} else {
				opts.onProcess && opts.onProcess(1);
				opts.onAnimationFinish && opts.onAnimationFinish();
			}
		};
		animationFrame(_step, delay);
	}

	function getPath(deg) {
		var path = '50% 50%'
		//各个锚点
		var ps = ['0% 0%', '100% 0%', '100% 100%', '0% 100%']
		var ps1 = path + ',' + ps[0]
		var ps2 = ps1 + ',' + ps[1]
		var ps3 = ps2 + ',' + ps[2]
		var ps4 = ps3 + ',' + ps[3]
		var ops = [
			function(per) { return ps1 + ',' + (per + '% 0%') },
			function(per) { return ps2 + ',' + ('100% ' + per + '%') },
			function(per) { return ps3 + ',' + (100 - per) + '% 100%' },
			function(per) { return ps4 + ',' + '0% ' + (100 - per) + '%' },
		]
		if (deg == 0) {
			return 'polygon(50% 50%, 50% 0%)'
		}
		else if (deg % 360 == 0) {
			return ''
		}
		var idx = parseInt(deg / 90) % 4
		var pdeg = deg % 90
		var per = pdeg / 90 * 100
		if(ops[idx]) {
			return 'polygon(' + ops[idx](per) + ')'
		}
		else {
			return ''
		}
	}

	function setDeg(newValue, oldValue, ownerInstance, instance) {
		var odeg = oldValue * 360
		var deg = newValue * 360
		var offset = deg - odeg
		
		var ds = instance.getDataset()
		if(!ds.animate) {
			var path = getPath(deg)
			instance.setStyle({
				'clip-path': path,
			})
			return
		}
		Animation({
			instance: ownerInstance,
			timing: 'easeInOut',
			duration: 300,
			onProcess: function onProcess(process) {
				var pdeg = odeg + process * offset
				var path = getPath(pdeg)
				var com = ownerInstance.selectComponent('.circle');
				com.setStyle({
					'clip-path': path,
				})
			},
			onAnimationFinish: function onAnimationFinish() {}
		});
	}
	module.exports = {
		pro: setDeg,
	}
</script>

<script>
	export default {
		props: {
			pro: {
				type: Number,
				default: 0
			},
			//起始位置 0-1
			start: {
				type: Number,
				default: 0,
			},
			//圆形大小
			size: {
				type: Number,
				default: 200
			},
			//线宽度
			border_width: {
				type: Number,
				default: 20
			},
			//线颜色
			border_color: {
				type: String,
				default: '#07C160',
			},
			//线背景色
			border_back_color: {
				type: String,
			},
			//中心内容背景色
			background: {
				type: String,
			},
			//单位
			unit: {
				type: String,
				default: 'rpx',
			},
			//是否启用动画
			animate:{
				type: Boolean,
				default: true,
			}
		},
		data() {
			return {
				cpro: 0,
			}
		},
		watch: {
			pro(val) {
				this.cpro = val
			}
		},
		mounted() {
			this.cpro = this.pro
		},
		methods: {
			sunit(num) {
				if(typeof num === 'number') {
					return num + this.unit
				}
			}
		}
	}
</script>

<style scoped lang="scss">
	.circle-progress-bar{
		position: relative;
	}
	.circle, .bg, .border-back {
		height: 100%;
		width: 100%;
		border-radius: 50%;
		position: absolute;
		box-sizing: border-box;
	}
	.circle{
		z-index: 1;
	}
	.border-back{
		height: calc(100% - 1px);
		width: calc(100% - 1px);
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
	}
	.point {
		position: absolute;
		border-radius: 50%;
		z-index: 1;
	}
	.center{
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		z-index: 2;
	}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/695078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT桌面挂件动画

目录 参考功能实现05DesktopPattern.promain.cppdesktoppattern.hdesktoppattern.cppwallpaper.hwallpaper.cpp 效果模糊知识点 参考 图片资源 功能 桌面挂件动画置顶切换挂件动画图片选择更换桌面壁纸显示时改变桌面壁纸&#xff0c;隐藏/退出时还原桌面壁纸系统托盘菜单&a…

R语言复现一篇6分的孟德尔随机化文章

上一期我们对孟德尔随机化做了一个简单的介绍&#xff0c;今天我们来复现一篇6分左右的使用了孟德尔随机化方法的文章&#xff0c;文章的题目是&#xff1a;Mendelian randomization analysis does not reveal a causal influence of mental diseases on osteoporosis&#xff…

Angular 与 PDF之五 实现方式的选择与扩展

在纯web的前提下&#xff08;不考虑移动端native&#xff09;&#xff0c;PDF的功能基本包括&#xff1a; 客户端PDF&#xff1a;最简单的场景&#xff0c;实现方式也很多&#xff0c;基本不需要有什么顾虑的地方&#xff0c;简单的实现可以参考系列第一篇文章。客户端PDF预览&…

【NM 2019】综述:基于机器学习引导的定向进化蛋白质工程

Machine-learning-guided directed evolution for protein engineering | Nature Methods Machine-learning-guided directed evolution for protein engineering 机器学习引导的定向进化蛋白质工程 图1 | 带和不带机器学习的定向进化。 a&#xff09;定向进化利用迭代循环的…

MySQL数据库---笔记5

MySQL数据库---笔记5 一、锁1.1、介绍1.2、全局锁1.2.1、全局锁介绍1.2.2、一致性数据备份 1.3、表级锁1.3.1、表锁1.3.2、元数据锁&#xff08;meta data lock , MDL&#xff09;1.3.3、意向锁 1.4、行级锁1.4.1、介绍1.4.2、行锁1.4.3、间隙锁/临建锁 二、InnoDB引擎2.1、逻辑…

vue和node使用websocket实现数据推送,实时聊天

需求&#xff1a;node做后端根据websocket&#xff0c;连接数据库&#xff0c;数据库的字段改变后&#xff0c;前端不用刷新页面也能更新到数据&#xff0c;前端也可以发送消息给后端&#xff0c;后端接受后把前端消息做处理再推送给前端展示 1.初始化node&#xff0c;生成pac…

STM32杂记之单片机复位状态

参考源码 概况 复位后&#xff0c;器件从内部高速振荡器 &#xff08;HSI 8MHz&#xff09; 运行&#xff0c;FLASH 0 等待状态&#xff0c;FLASH预取缓冲区使能&#xff0c;除内部 SRAM、FLASH和 JTAG 外&#xff0c;所有外设均关闭。高速 &#xff08;AHB&#xff09; 和低…

LLaMA模型微调版本:斯坦福 Alpaca 详解

项目代码&#xff1a;https://github.com/tatsu-lab/stanford_alpaca 博客介绍&#xff1a;https://crfm.stanford.edu/2023/03/13/alpaca.html Alpaca 总览 Alpaca 是 LLaMA-7B 的微调版本&#xff0c;使用Self-instruct[2]方式借用text-davinct-003构建了52K的数据&#x…

三相一次重合闸程序逻辑原理(二)

在手动合闸至故障线路或手动分闸及保护或自动装置要求不允许重合闸&#xff08;如母线、变压器保护及低频减载动作&#xff09;等情况下&#xff0c;闭锁重合闸的输入开关量触点接通&#xff0c;H4输出“1”&#xff0c;非门Z4输出“0”&#xff0c;计数器清零&#xff08;CD0&…

健身戴哪种耳机好、适合健身运动的耳机推荐

随着越来越多的人加入运动健身的行列&#xff0c;市场上涌现出越来越多适用于跑步的运动耳机。对于喜欢运动的朋友们来说&#xff0c;一副优秀的运动耳机成为了必不可少的装备。当进行力量训练时&#xff0c;佩戴耳机可以帮助提升训练的专注度&#xff1b;而在进行有氧运动时&a…

部署 kubeadm 1.20

目录 一、环境准备二、所有节点安装docker三、所有节点安装kubeadm&#xff0c;kubelet和kubectl四、部署K8S集群 硬件准备 master&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&#xff09; 192.168.154.10 docker、kubeadm、kubelet、kubectl、flannel node01&#xff08…

oracle dblink mysql查询text无法显示问题

帮客户做了一个oracle到mysql的dblink之后&#xff0c;客户反馈发现有的表查询字段不全&#xff0c;通过select * 查询&#xff0c;mysql中有个字段INTERVENTION字段没有显示&#xff0c;首先想到的就是可能不支持查询&#xff0c;检查这个字段类型为text&#xff0c;猜测可能是…

LeetCode刷题 | 139. 单词拆分

139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 示例 1&#xff1a; 输入: s "leetcode"…

直播预约|湘江公益直播大讲堂:以低代码助力中小企业数字化转型

在当今数字时代&#xff0c;中小企业面临着前所未有的机遇和挑战。在激烈的商业竞争环境中&#xff0c;如何快速、高效地实现数字化转型并提升企业的竞争力成为中小企业亟需解决的关键问题。 低代码平台的兴起&#xff0c;为中小企业的数字化转型带来了全新的解决方案。 6月29日…

企业级ChatGPT开发的三大核心内幕及案例实战(二)

2.2 企业级ChatGPT开发的三大核心剖析 Gavin老师:NLP_Matrix_Space 本节讲解LangChain官方提供的一个项目,跟大家展示企业级开发的核心元素,如图2-1所示,是项目的架构示意图。 图2- 1 LangChain项目架构示意图 一个基本原则是你的提示词和模型进行交互,作为和模型交互的…

如何用rust实现一个异步channel

目录 前言思路实现功能代码实现 测试先引测试版包测试代码结果与分析思考 尾语 前言 使用通信来共享内存&#xff0c;而不是通过共享内存来通信 上面这句话&#xff0c;是每个go开发者在 处理多线程通信时 的座右铭&#xff0c;go甚至把实现这个理念的channel直接焊在编译器里&…

台灯太亮会影响视力吗?选灯一定要注意这几个点!

灯太亮对眼睛有没有影响&#xff0c;取决于灯“亮”的程度和使用的时间。如果是偶尔有需求&#xff0c;灯过于亮&#xff0c;使用时间不长的话对眼睛倒是没有太大的影响。但如果是长时间使用的&#xff0c;就不能使用过亮的灯了&#xff0c;容易导致睫状肌代偿性收缩、导致眼睛…

RISC-V处理器的设计与实现(三)—— 上板验证

文章目录 RISC-V处理器的设计与实现&#xff08;一&#xff09;—— 基本指令集_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现&#xff08;二&#xff09;—— CPU框架设计_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现&#xff08;三&#xff09;—— 上板验…

人机混合智能概述

人机混合智能是指将人类的智能和计算机的智能结合起来&#xff0c;实现更加智能化的决策和行动。人机混合智能的发展历史可以追溯到20世纪50年代早期&#xff0c;当时计算机还是庞大的机器&#xff0c;只能由专业人员操作。但随着计算机技术的不断发展&#xff0c;出现了更为普…

JavaScript之鼠标事件、坐标轴、定位、clientXY、offsetXY、layerXY、pageXY、screenXY

文章目录 MouseEvent的事件类别阻止鼠标的默认事件去除单击右键菜单阻止图像默认拖拽阻止文字的拖拽和选择阻止表单提交及重置打印输出MouseEvent对象内容clientX和clientY与x和yoffsetXYlayerXYpageXYscreenXY总结 MouseEvent的事件类别 序号事件描述1mousedown鼠标按下2mouse…